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

我正在尝试使用Newtonsoft JsonConverter序列化C#DataTable

代码:

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相比,性能是白天和黑夜。

任何帮助将不胜感激

您可以使用以下JsonConverter执行此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().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(); } } 

这是一个演示它的工作小提琴 。 有关更多信息,请参阅Custom JsonConverter上的Newtonsoft文档 。

DataTableJsonConverter

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