【问题标题】:How can I serialize object without some property names如何在没有某些属性名称的情况下序列化对象
【发布时间】:2017-01-14 09:11:06
【问题描述】:

我想生成以下 json 输出。我尝试序列化对象,但正如您从输出中看到的那样,“数据”数组没有 json 字符串名称,如果它被序列化,它会将属性名称添加到数组中。请为此提出解决方案并以通用方式对其进行优化。这是虚拟数据原始数据将是动态的。

[
    {
        "data": [[0, -74984809.4603082], [1, -1547043466.02543], [2, 1197200673.15602], [3, -1329017076.87315]],
        "label": "Sine Wave"
    },
    {
        "data": [[0, -16009669.0446502], [1, -1349266386.03401], [2, 1730901576.10012], [3, -48303271.446511]],
        "label": "Cosine Wave"
    },
    {
        "data": [[0, -22114801.1769572], [1, 1737206285.30856], [2, 1280894300.93367], [3, -14969166.212896]],
        "label": "Sine2 Wave"
    },
    {
        "data": [[0, -236097551.627018], [1, 8971833.78377865], [2, -805237017.202245], [3, -28865332.2392996]],
        "label": "Cosine2 Wave"
    }
]

我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.UI;
using Microsoft.Ajax.Utilities;

namespace D3WebApp
{
    public partial class _Default : Page
    {
        public class Datum
        {
            public int No { get; set; }

            public double Value { get; set; }
        }
        public class LineGraphData
        {
            public Datum Data { get; set; }

            public string Label { get; set; }
        }

        public class GraphData
        {
            public Datum[] Data { get; set; }

            public string Label { get; set; }
        }
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [WebMethod]
        public static string GetData()
        {
            return GetDataForChart(); ;
        }

        private static string GetDataForChart()
        {
            var r1 = new Random();
            var r2 = new Random();
            var r3 = new Random();
            var r4 = new Random();
            var datalist = new List<LineGraphData>();

            for (var i = 0; i < 4; i++)
            {

                datalist.Add(new LineGraphData()
                {
                    Data = new Datum()
                    {
                        No = i,
                        Value = r1.Next() * Math.Sin(r2.Next() + i / (10 * (r4.Next() + .5)))
                    },
                    Label = "Sine Wave"
                });

                datalist.Add(new LineGraphData()
                {
                    Data = new Datum()
                    {
                        No = i,
                        Value = r2.Next() * Math.Sin(r3.Next() + i / (10 * (r3.Next() + .5)))
                    },
                    Label = "Cosine Wave"
                });
                datalist.Add(new LineGraphData()
                {
                    Data = new Datum()
                    {
                        No = i,
                        Value = r3.Next() * Math.Sin(r1.Next() + i / (10 * (r2.Next() + .5)))
                    },
                    Label = "Sine2 Wave"
                });

                datalist.Add(new LineGraphData()
                {
                    Data = new Datum()
                    {
                        No = i,
                        Value = r4.Next() * Math.Sin(r4.Next() + i / (10 * (r1.Next() + .5)))
                    },
                    Label = "Cosine2 Wave"
                });
            }

            var sb = new StringBuilder();
            var valuelist = new List<GraphData>();
            //want to remove this or make it cleaner
            foreach (var result in datalist.DistinctBy(x => x.Label).Select(x => x.Label))
            {
                var childItems = datalist.
                    Where(x => x.Label == result).Select(x => x.Data).ToList();

                valuelist.Add(new GraphData() { Label = result, Data = childItems.ToArray() });

                sb.Append(@"{""data"":");
                sb.Append("[");

                foreach (var value in childItems)
                {
                    sb.Append(string.Format("[{0},{1}],", value.No, value.Value));
                }

                var index = sb.ToString().LastIndexOf(',');

                if (index >= 0)
                    sb.Remove(index, 1);

                sb.Append("],");
                sb.Append(string.Format(@"""{0}"":""{1}""", "label", result));
                sb.Append("},");
            }
            var testdata = new JavaScriptSerializer().Serialize(valuelist);
            var datastr = "[" + sb.ToString().Trim(',') + "]";
            return datastr;
        }
    }
}

【问题讨论】:

  • 不要手动构建json,应该使用Json.Net序列化器或类似的
  • 是否可以从输出中删除属性名称。

标签: c# asp.net json serialization


【解决方案1】:

请在此处使用Newtonsoft.JSON 和 Linq 方法 GroupBy:

    var datalistDynamic = datalist.GroupBy(it => it.Label).Select(
        dataItemGrouped => new
        {
            Label = dataItemGrouped.Key,
            Data = dataItemGrouped.Select(dataItem => new[] {dataItem.Data.No, dataItem.Data.Value})
        }).ToArray();
    var datastr = JsonConvert.SerializeObject(datalistDynamic);
    return datastr;

并且可以删除此代码:

   var sb = new StringBuilder();
            var valuelist = new List<GraphData>();
            //want to remove this or make it cleaner
            foreach (var result in datalist.DistinctBy(x => x.Label).Select(x => x.Label))
            {
                var childItems = datalist.
                    Where(x => x.Label == result).Select(x => x.Data).ToList();

                valuelist.Add(new GraphData() { Label = result, Data = childItems.ToArray() });

                sb.Append(@"{""data"":");
                sb.Append("[");

                foreach (var value in childItems)
                {
                    sb.Append(string.Format("[{0},{1}],", value.No, value.Value));
                }

                var index = sb.ToString().LastIndexOf(',');

                if (index >= 0)
                    sb.Remove(index, 1);

                sb.Append("],");
                sb.Append(string.Format(@"""{0}"":""{1}""", "label", result));
                sb.Append("},");
            }
            var testdata = new JavaScriptSerializer().Serialize(valuelist);
            var datastr = "[" + sb.ToString().Trim(',') + "]";

如果要忽略属性,请使用属性JsonIgnore,例如

  public class GraphData
    {
        public Datum[] Data { get; set; }

        [JsonIgnore]
        public string Label { get; set; }
    }

【讨论】:

  • 如何从序列化字符串中删除 x,y 名称 {"Data":{"x":0,"y":-707488064.82221842},"Label":"Sine2 Wave"},{ "Data":{"x":0,"y":-1627302835.6074553},"Label":"Cosine2 Wave"},名称 Data 应该在那里,但 x,y 不应该。
  • 将 JsonIgnore 属性放在 Data 类中的 x 和 y 属性上
  • 它将完全忽略,我只想删除名称。它应该像 {"Data":{:0,:-707488064.82221842},"Label":"Sine2 Wave"},{"Data":{:0,:-1627302835.6074553},"Label":"Cosi‌​ne2 Wave"},值应该没有属性名称。
  • @shijithmc 是无效的 json
【解决方案2】:

如果您想在序列化后获得 Json 输出,就像在您的问题中发布的那样。你应该遵循这个类层次结构:

public class Sample
{
    [JsonProperty("data")]
    public List<List<double>> Data { get; set; }

    [JsonProperty("label")]
    public string Label { get; set; }
}

然后您应该创建应通过 Json.Net 序列化的样本数组

var samples = new List<Sample>();
samples.Add(new Sample()
{
    Data = new List<List<double>>()
    {
        new List<double> { 0, 6.48 },
        new List<double> { 1, 6.43 }
        //...other values
    },
    Label = "Port-1"
};
string json = JsonConvert.SerializeObject(samples);

【讨论】:

  • 这只允许一个值,我需要 x 和 y 像 [1,9] 我们不能有像 [JsonProperty("data")] 这样的列表 public List, List > 数据 { 获取;放;如果我错了,请纠正我。
  • @shijithmc 你错了,因为你需要数组数组来符合发布的 json 结构。在您的情况下,您必须创建点数组 (x,y)(即 Data 属性)。但是,每个点都由两个元素组成的数组表示(第一个元素是 x,第二个元素是 y)。
  • 您能否提供一个示例我如何添加 [{"data":[[0,6.48],[1,6.43],[2,6.43],[3,6.45],[ 4,6.44],[5,6.40],[6,6.43],[7,6.43],[8,6.40],[9,0.21],[13,5.39],[14,1.69],[15, 8.75]],"label":"Port-1"} x 和 y
  • @shijithmc 我已经编辑了初始示例,如您所见,建议的 Json 结构可能不适合您的需求。如果你有可能,我强烈建议你改变你的 json 结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多