【问题标题】:Newtsonsoft.Json - Deserialize JSON with nested arrays to DataTableNewtonsoft.Json - 将带有嵌套数组的 JSON 反序列化为 DataTable
【发布时间】:2018-02-10 15:01:54
【问题描述】:

我需要将下面的 Json 字符串转换为 DataTable。

Json 示例:

[
    {
        'extension': '0001',
        'name': 'User 1',
        'email': 'user1@mail.se',
        'mobile': '+46000000',
        'profile': {
        'available': false,
        'name': 'Gone for the day',
        'until': '2017-09-01 08:00:00',
        'message': 'Do not call me'
    },
        'calls': [],
    },
    {
        'extension': '0002',
        'name': 'User 2',
        'email': 'user2@mail.se',
        'mobile': '+46000000',
        'profile': {
        'available': false,
        'name': 'Gone for the day',
        'until': '2017-09-01 08:00:00',
        'message': 'Do not call me'
    },
        'calls': [],
    }
]

我可以阅读“个人资料”之前的所有内容:,我如何访问个人资料下的下一级数据? (profile.avialable,profile.name, profile.until, profile.message) 并将其添加到数据表?

这是我的课

public class Profile
{
    public bool available { get; set; }
    public string name { get; set; }
    public string until { get; set; }
    public object message { get; set; }
}


public class RootObject
{
    public string name { get; set; }
    public string extension { get; set; }
    public string mobile { get; set; }
    public Profile profile { get; set; }
}

这是我的代码

public static DataTable ToDataTable<T>(List<T> items)
{
    DataTable dataTable = new DataTable(typeof(T).Name);

    //Get all the properties
    System.Reflection.PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (PropertyInfo prop in Props)
    {
        //Defining type of data column gives proper data table 
        var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
        //Setting column names as Property names
        dataTable.Columns.Add(prop.Name, type);
    }
    foreach (T item in items)
    {
        var values = new object[Props.Length];
        for (int i = 0; i < Props.Length; i++)
        {
            //inserting property values to datatable rows
            values[i] = Props[i].GetValue(item, null);
        }
        dataTable.Rows.Add(values);
    }
    //put a breakpoint here and check datatable
    return dataTable;
}


PopulateList()
{          
    var data = JsonConvert.DeserializeObject<List<RootObject>>(JsonData);
    DataTable dt = ToDataTable(data);

    GridView1.DataSource = dt;
    GridView1.DataBind();
}

JsonData 包含我的 JSON 的位置

有人知道吗?

【问题讨论】:

  • 实际问题是什么?你说“如何进入下一个级别”是什么意思?你想在哪里访问它?
  • 如果实际问题是嵌套类转换为 DataTable(与反序列化和 json 无关!)那么你真的需要 DataTable 吗?你不能使用 List/BindingList 吗?是的,有很多问题,因为你的问题很模糊。
  • 你说得对,问题可能很模糊,json 来自电话交换机的 API,目标是创建一个包含联系人和个人资料信息的动态电话列表。它需要是一个包含名称、扩展名、移动、profile.avialable、profile.name、profile.until 列的表

标签: c# asp.net json datatable


【解决方案1】:

如果我的理解正确,您希望在同一行的“个人资料”下显示数据,因此每一行看起来像 {"name", "extension", "mobile", "profile.available", “profile.name”、“profile.until”、“profile.message”}。

问题是代码根据 RootObject 类中的对象类型(名称、扩展名、移动设备、配置文件)添加列,并且没有进一步研究它们的类型以查看它们是否进一步具有任何属性。

在这部分代码中:

foreach (PropertyInfo prop in Props)
{
    var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.
    dataTable.Columns.Add(prop.Name, type);
}

您必须添加检查以查看 RootObject 中的对象是否具有任何其他属性。 基于此,您还必须更改第二个循环,以考虑添加到表中每一行数据的子属性。

【讨论】:

  • 如何重写公共静态 DataTable ToDataTable(List items) 函数来处理配置文件值?
  • 没有人有示例如何做到这一点?
【解决方案2】:

Json 工作正常

    string JsonData = @"[
        {
        'extension': '0001',
        'name': 'User 1',
        'email': 'user1@mail.se',
        'mobile': '+46000000',
        'profile': {
        'available': false,
        'name': 'Gone for the day',
        'until': '2017-09-01 08:00:00',
        'message': 'Do not call me'
        },
        }
        ]";
    var data = JsonConvert.DeserializeObject<List<RootObject>>(JsonData); 

RootObjects 包含有效的Profile objectsm 问题不在于 Json 解析器。在dataTable.Rows.Add(values); 中,您的values 属性是“有效的”(它包含正确且已填充的Profile 对象)。检查您是否使用有效的方法将数据传递到数据库中。

【讨论】:

  • 如果我尝试将数据直接绑定到网格视图而不将其转换为数据表,我会获取扩展名、名称、电子邮件、移动运行示例的数据。
  • 如何重写公共静态 DataTable ToDataTable(List items) 函数来处理配置文件值?
猜你喜欢
  • 2017-08-25
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多