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

C# 使用Newtonsoft自定义JSON字符串输出,c#,json.net,C#,Json.net,我正在尝试使用Newtonsoft JsonConverter序列化C#数据表 代码: JsonConvert.SerializeObject(dt); //dt is DataTable 我得到的结果是: [ { "Name": "Tiger Nixon", "Position": "System Architect", "Address": "Edinburgh", "No": "5421" }, { "Name": "Garrett W

我正在尝试使用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"
    ]
  ]
}
是否可以使用Newtonsoft自定义输出?我尝试编写自己的代码,通过在
DataTable
上使用
foreach
对DataTable进行序列化,但与Newtonsoft相比,性能日以继夜


任何帮助都将不胜感激

以下是我在阅读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();

    }
}
公共类JqueryDatatablesConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(DataTable).IsAssignableFrom(objectType);
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
抛出新的NotImplementedException();
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
动态dt=(数据表)值;
动态计数=dt.Columns.count-1;
writer.WriteStartObject();
writer.WritePropertyName(“数据”);
writer.writestarray();
foreach(数据行dr在dt.行中){
writer.writestarray();

对于(int x=0;x,您可以使用以下方法:

请注意,我使用时需要引用
System.Data.DataSetExtensions.dll

此处是。有关更多信息,请参阅

DataTableJsonConverter 将
数据表
转换为自定义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);
    }
}
下面是如何使用它 演出 对于那些感兴趣的人来说,这里有三种不同的方法,分别是me、dbc和 warheat1990超过1500个数据行,每行运行两次。它们都非常接近,并且由于我不知道的原因,第二次运行总是更快

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

这对您有帮助吗?这是Newtonsoft的直接文档:您只需要序列化,还是也需要反序列化?如果没有列名,反序列化到
DataTable
看起来有问题。@JasonWilczak:工作很有魅力!但是您知道为什么与我自己的代码相比,性能非常显著。我是说我的代码很慢,因为我循环处理大型数据表。我对自定义JsonConverter做了同样的事情,但速度非常快。我做了一些性能测试,我的代码性能稍好一些(毫秒,所以没关系)但是你的答案要简单得多。谢谢!谢谢。与显式循环相比,Linq有时会增加一点性能影响;当Json.NET反映中间表示时,也可能会有性能影响。
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"
    ]
  ]
}
DataTableJsonConverter:6 ms
DataTableJsonConverter:2 ms
DataTableTo2dArrayConverter:251 ms
DataTableTo2dArrayConverter:11 ms
JqueryDatatablesConverter:1580 ms
JqueryDatatablesConverter:16 ms