Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用JsonConvert.DeserializeObject将json文本反序列化到C中的对象列表_C#_Json - Fatal编程技术网

C# 如何使用JsonConvert.DeserializeObject将json文本反序列化到C中的对象列表

C# 如何使用JsonConvert.DeserializeObject将json文本反序列化到C中的对象列表,c#,json,C#,Json,我有如下所示的JSON数据。我只包含一次列名以保存数据大小。请让我知道如何将此转换为C对象列表 // JSON { "COLUMNS": [ "id", "country","lastname", "firstname", "email", "category" ], "DATA": [ [43, "USA", "jon", "doe", "doe@gmail.com", "HR"], [44, "JAPAN", "ta

我有如下所示的JSON数据。我只包含一次列名以保存数据大小。请让我知道如何将此转换为C对象列表

// JSON
{
    "COLUMNS": [
        "id", "country","lastname", "firstname", "email", "category"
    ], 
    "DATA": [
        [43, "USA", "jon", "doe", "doe@gmail.com", "HR"], 
        [44, "JAPAN", "tanaka", "yidi", "yidi@aol.com", "IT"]
    ]
}

// .NET
Employee emp = JsonConvert.DeserializeObject<Employee>(jsonData);  
我应该能够访问对象属性,比如emp.lastname


另外,正如标题所示,我正在使用中。

您将无法直接使用JsonConvert类,因为它希望所有属性都有一个名称/映射,并且无法确定它,因为您基本上使用的是自定义格式

您需要做的是创建一个包含列和数据的类,并序列化为该类,如下所示:

class CustomData
{
    public string Columns { get; set; }
    public object[,] Data { get; set; }
}
JsonConvert应该能够在.NET中将数据转换成这种结构

从那以后,它就变成了一个.NET问题,因为您必须获得列和数据的名称。您应该能够使用LINQ帮助将两者配对,然后使用反射填充您的项目:

// The custom data structure, deserialized from JSON.
CustomData data = ...;

// The type of Employee.
Type type = typeof(Employee);

// Create a map of the property info to the ordinal in the
// Columns.
IDictionary<int, PropertyInfo> propertyMap = data.Columns.
    Select((p, i) => 
        new { Index = i, PropertyInfo = type.GetProperty(p) }).
    ToDictionary(p => p.Index, p => p.PropertyInfo);

// Cycle through the rows in the data.
var query =
    // Cycle through all of the rows.
    from row in Enumerable.Range(0, data.Data.GetLength(0))

    // Create the instance.
    let instance = new Employee()

    // For each column in the row.
    from column in Enumerable.Range(0, data.Data.GetLength(1))

    // Lookup the property info.
    let propertyInfo = propertyMap[column]

    // Select the instance, the property, and the value.
    select { 
        // This is used for grouping purposes, since
        // you can't guarantee that the type you are serializing
        // to will have natural identity properties and
        // you know the row corresponds to one singular instance.
        Row = row,
        Instance = instance, 
        PropertyInfo = propertyInfo,
        Value = data.Data[row, column]
    };

// Iterate through the items, setting the instance values.
foreach (var propertyAndData in query)
{
    // Set the property value on the instance.
    propertyAndData.PropertyInfo.
        SetValue(propertyAndData.Instance, Value, null);
}

// Group by the row and get the first item in each sequence.
IEnumerable<Employee> employees =
    from item in query
    groupby item by item.Row into g
    select g.First();
以上的唯一警告;如果您使用的是值类型,那么在迭代时将不会填充相同的实例。为了处理值类型,您必须展开LINQ查询,并使用for循环遍历每一行和每一列,在每一新行上创建新实例,然后如上所述使用反射填充属性