【问题标题】:JSON object to Datatable in C#JSON对象到C#中的数据表
【发布时间】:2016-08-27 05:45:27
【问题描述】:

我有以下 c# 类

public class Output
        {
            public string name { get; set; }
            public string[] results { get; set; }
        }

执行后输出如下

[
  {
    "name": "Field1",
    "results": [
      "One",
      "Two",
      "Three"
    ]
  },
  {
    "name": "Field2",
    "results": [
      "One",
      "Two",
      "Three",
      "Four"
    ]
  }
]

是否有任何实用程序或库可以将我的 JSON 转换为 DataTable。我检查了JSON.net example,但要求 JSON 必须采用以下格式才能将其转换为表格

string json = @"[{"Field1" : "One", "Field2": "One"}
{"Field1" : "Two", "Field2": "Two"}
{"Field1" : "Three", "Field2": "Three"}
{"Field1" : "", "Field2": "Four"}];

var table = JsonConvert.DeserializeObject<DataTable>(json);

另外,我的 JSON 是否可以转换为 JsonConvert.DeserializeObject 所需的格式的任何线索

这不是重复的,标记为重复的问题讨论了最好的方法,而不是我在此处提供的复杂 JSON 格式示例。

预期输出

Field1,  Field2
One, One
Two, Two
Three, Three
null,Four

【问题讨论】:

  • 你如何创建这个 JSON?
  • 通过从html文件中解析一些数据
  • 你的DataTable应该有什么结构?从您的示例中,我得出结论您想要 2 列:Field1 和 Field2,对吗?
  • @AntonMaiorov 正确。但是可能字段比较多,所以需要foreach循环

标签: c# json datatable


【解决方案1】:

JsonConver.DeserializeObject 没有为您提供实现目标的简单方法。从Outputs 到DataTable 的列表中编写一个简单的解析器会容易得多。我给你代码:

public static class Helper
{
    public static DataTable ToDataTable(this List<Program.Output> list)
    {
        var dt = new DataTable();

        // insert enough amount of rows
        var numRows = list.Select(x => x.results.Length).Max();
        for (int i = 0; i < numRows; i++)
            dt.Rows.Add(dt.NewRow());

        // process the data
        foreach (var field in list)
        {
            dt.Columns.Add(field.name);
            for (int i = 0; i < numRows; i++)
                // replacing missing values with empty strings
                dt.Rows[i][field.name] = i < field.results.Length ? field.results[i] : string.Empty; 
        }

        return dt;
    }
}

以及用法示例:

public class Program
{
    static void Main(string[] args)
    {
        var s = "[{\"name\": \"Field1\", \"results\": [\"One\", \"Two\", \"Three\"]}, {\"name\": \"Field2\", \"results\": [\"One\", \"Two\", \"Three\", \"Four\"]}]";
        var o = JsonConvert.DeserializeObject<List<Output>>(s);
        // convert the list to a DataTable
        var dt = o.ToDataTable();
    }

    public class Output
    {
        public string name { get; set; }
        public string[] results { get; set; }
    }
}

【讨论】:

  • 由于 Program.Output 难以访问而出现错误,知道吗?
  • @PrinceRathee 公开输出类 :)
  • 谢谢,太棒了!
【解决方案2】:

我建议将您的 JSON 转换回输出对象数组。为此,您可以使用 JsonDataContractSerializer(需要注释)或 JavascriptSerializer(需要引用 System.Web.Extensions)。

拥有一组输出对象,您可以执行以下操作:

DataTable ConstructDataTable(Output[] outputArray)
{
  var table = new DataTable();
  var columnNames = outputArray.Select(i => i.name).Distinct().ToArray();
  var rows = outputArray.SelectMany(i => i.result).Distinct().ToArray();
  foreach(var cn in columnNames)
     table.Columns.Add(cn, typeof(string));
  foreach(var r in rows)
  {
    object[] values = new object[columnNames.Length];
    for (int i = 0; i < columnNames.Length; i++)
    {
      values[i] = outputArray.First(i => i.name == columnNames[i]).results.FirstOrDefault(i => i == r);
    }
    table.Rows.Add(values);
  }
  return table;
}

【讨论】:

    【解决方案3】:
    DataTable dt = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
    

    【讨论】:

      【解决方案4】:

      您可以做的是将 JSON 数据转换回对象列表,例如

      JsonConvert.DeserializeObject<List<CustomerJson>>(json);
      

      然后用转换器方法将其转换为DataTable

      public static DataTable ToDataTable<T>(this IList<T> data)
      {
          PropertyDescriptorCollection props =
              TypeDescriptor.GetProperties(typeof(T));
          DataTable table = new DataTable();
          for(int i = 0 ; i < props.Count ; i++)
          {
              PropertyDescriptor prop = props[i];
              table.Columns.Add(prop.Name, prop.PropertyType);
          }
          object[] values = new object[props.Count];
          foreach (T item in data)
          {
              for (int i = 0; i < values.Length; i++)
              {
                  values[i] = props[i].GetValue(item);
              }
              table.Rows.Add(values);
          }
          return table;        
      }
      

      【讨论】:

      • 只添加了两行,但按照上面的示例应该是 4。 (见预期输出)
      • 你调试过看看哪里发生了什么吗?可能出现错误?
      • 现在检查,我以为你已经测试过了,但我缺少任何东西。
      【解决方案5】:

      使用过的参考资料:

        using Newtonsoft.Json;
        using System.Collections.Generic;
        using System.Data;
        using System.IO;
        using FastMember;
      

      你的班级:

        public class Output
        {
              public string name { get; set; }
              public string[] results { get; set; }
        }
      

      还有:

              var s = "[{\"name\": \"Field1\", \"results\": [\"One\", \"Two\", \"Three\"]}, {\"name\": \"Field2\", \"results\": [\"One\", \"Two\", \"Three\", \"Four\"]}]";
              List<Output> data = JsonConvert.DeserializeObject<List<Output>>(s);
      
              DataTable dt = new DataTable(); 
              using (var reader = ObjectReader.Create(data))
              {
                  dt.Load(reader);
              }
      

      【讨论】:

        猜你喜欢
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-22
        相关资源
        最近更新 更多