使用 Newtonsoft 的自定义 JSON 字符串输出



我正在尝试使用Newtonsoft JsonConverter序列化C#数据表

法典:

JsonConvert.SerializeObject(dt); //dt is DataTable

我得到的结果是:

[
  {
    "Name": "Tiger Nixon",
    "Position": "System Architect",
    "Address": "Edinburgh",
    "No": "5421"
  },
  {
    "Name": "Garrett Winters",
    "Position": "Accountant",
    "Address": "Tokyo",
    "No": "8422"
  }
]

我想要的结果是:

{
  "data": [
    [
      "Tiger Nixon",
      "System Architect",
      "Edinburgh",
      "5421"
    ],
    [
      "Garrett Winters",
      "Accountant",
      "Tokyo",
      "8422"
    ]
  ]
}

是否可以使用牛顿软件自定义输出?我尝试编写自己的代码来通过在DataTable上使用foreach来序列化DataTable,但与Newtonsoft相比,性能是白天和黑夜。

任何帮助将不胜感激

您可以使用

以下JsonConverter来做到这一点:

public class DataTableTo2dArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(DataTable).IsAssignableFrom(objectType);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var table = (DataTable)value;
        var array2d = table.AsEnumerable().Select(row => table.Columns.Cast<DataColumn>().Select(col => row[col]));
        serializer.Serialize(writer, new { data = array2d });
    }
}

然后像这样使用它:

        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new DataTableTo2dArrayConverter());
        var json = JsonConvert.SerializeObject(dt, Formatting.Indented, settings);

请注意,我对System.Data.DataTableExtensions.AsEnumerable()的使用需要引用 System.Data.DataSetExtensions.dll

这是我在阅读JasonWilczak提供的链接后的做法

public class JqueryDatatablesConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(DataTable).IsAssignableFrom(objectType);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        dynamic dt = (DataTable)value;
        dynamic count = dt.Columns.Count - 1;
        writer.WriteStartObject();
        writer.WritePropertyName("data");
        writer.WriteStartArray();
        foreach (DataRow dr in dt.Rows) {
            writer.WriteStartArray();
            for (int x = 0; x <= count; x++) {
                serializer.Serialize(writer, dr[x]);
            }
            writer.WriteEndArray();
        }
        writer.WriteEndArray();
        writer.WriteEndObject();
    }
}

这是一个演示它的工作小提琴。有关详细信息,请参阅有关自定义 JsonConverter 的 Newtonsoft 文档。

数据表Json转换器

DataTable转换为自定义 JSON 字符串。

public class DataTableJsonConverter : JsonConverter
{
    public override void WriteJson(JsonWriter w, object v, JsonSerializer s)
    {
        w.WriteStartObject();
        w.WritePropertyName("data");
        w.WriteStartArray();
        foreach(DataRow r in (v as DataTable).Rows)
        {
            w.WriteStartArray();
            foreach(var c in r.ItemArray)
            {
                w.WriteValue(c);
            }
            w.WriteEndArray();
        }
        w.WriteEndArray();
        w.WriteEndObject();
    }
    public override object ReadJson(JsonReader r, Type t, object v, JsonSerializer s)
    {
        throw new NotImplementedException("Unnecessary: CanRead is false.");
    }
    public override bool CanRead { get { return false; } }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DataTable);
    }
}

这是如何使用它

public class Program
{
    public static void Main()
    {
        var dt = SeedData();
        var json = JsonConvert.SerializeObject(
                dt, Newtonsoft.Json.Formatting.Indented,
                new DataTableJsonConverter());
        Console.WriteLine(json);
    }
    public static DataTable SeedData()
    {
        var dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Position");
        for (var i = 0; i < 2; ++i)
        {
            dt.Rows.Add(new object[] { "Shaun", "Developer" });
        }
        return dt;
    }
}

这是它的输出

{
  "data": [
    [
      "Shaun",
      "Developer"
    ],
    [
      "Shaun",
      "Developer"
    ]
  ]
}

性能

对于那些感兴趣的人,这里有一个小提琴的分支,它试图展示我、dbc 和Warheat1990 超过 1500 个数据行,每个行运行两次。它们都非常接近,由于我不知道的原因,第二次运行总是更快。

DataTableJsonConverter:6 ms
DataTableJsonConverter:2 ms
DataTableTo2dArrayConverter:251 ms
DataTableTo2dArrayConverter:11 ms
JqueryDatatablesConverter:1580 ms
JqueryDatatablesConverter:16 ms

相关内容

  • 没有找到相关文章

最新更新