使用 Newtonsoft.JSON 解析动态 JSON 在反序列化对象中缺少数组
Parsing dynamic JSON with Newtonsoft.JSON is missing array in the deserialized object
当我到达第三个循环时,它爆炸了,因为它找不到 table 上的 "Row"。为什么?
var converter = new ExpandoObjectConverter();
dynamic deserializeObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
foreach (var model in deserializeObject.Model)
{
foreach (var table in model.Table)
{
foreach (var row in table.Row)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
}
JSON:
{
"Model": [
{
"Field1": "Field1Value",
"Field2": "Field2Value",
"Field3": "Field3Value",
"Table": {
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "2",
"BookName": "Asp.Net 4 Blue Book",
"Category": "Programming",
"Price": "56.00"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
},
{
"ClientFirstName": "Jane",
"ClientLastName": "Doe",
"Table": [
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
},
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
]
}
]
}
问题不在于您反序列化对象的方式。您的 json 与包含 table 的两个对象不同。
第一个对象是一个 table,它有一个行数组:
"Table": {
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "2",
"BookName": "Asp.Net 4 Blue Book",
"Category": "Programming",
"Price": "56.00"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
}
你的第二个客户端对象有一个数组的数组。此外,在 table 数组之外的客户端对象中还有第二个行数组。
"Table": [
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
},
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
我建议要么以不同的方式格式化您的 json,要么创建一种不同的方法来遍历您在 json 中拥有的两种类型的 table。一个是对象,一个是数组。
例如。我将您的动态更改为 Newtonsoft.Json.Linq 中的 Newtonsoft Jobject;这将在两个 table 上出现,一个是对象,第二个是数组。
var converter = new ExpandoObjectConverter();
var deserializeObject = JsonConvert.DeserializeObject<JObject>(jsonString, converter);
foreach(var v in deserializeObject["Model"])
{
if(v["Table"] != null && v["Table"].Type == JTokenType.Object)
{
foreach (var x in v["Table"]["Row"])
{
Console.Write(x["BookId"] + " : " + x["BookName"] + Environment.NewLine);
}
}
else if (v["Table"].Type == JTokenType.Array)
{
foreach(var subTable in v["Table"])
{
foreach (var row in subTable["Row"])
{
Console.Write(row["BookId"] + " : " + row["BookName"] + Environment.NewLine);
}
}
}
}
您的 JSON 中的 Table
属性 在一个实例中被格式化为数组,在另一个实例中被格式化为对象。前者反序列化为List<object>
,后者反序列化为KeyValuePair<string, object>
。
您可以检查当前实例中的 Table
是否为 KeyValuePair<string, object>
类型,然后相应地进行:
foreach (var model in deserializeObject.Model)
{
foreach (var table in model.Table)
{
if(table is KeyValuePair<string, object>)
{
foreach (var row in table.Value)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
else
{
foreach (var row in table.Row)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
}
}
当我到达第三个循环时,它爆炸了,因为它找不到 table 上的 "Row"。为什么?
var converter = new ExpandoObjectConverter();
dynamic deserializeObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
foreach (var model in deserializeObject.Model)
{
foreach (var table in model.Table)
{
foreach (var row in table.Row)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
}
JSON:
{
"Model": [
{
"Field1": "Field1Value",
"Field2": "Field2Value",
"Field3": "Field3Value",
"Table": {
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "2",
"BookName": "Asp.Net 4 Blue Book",
"Category": "Programming",
"Price": "56.00"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
},
{
"ClientFirstName": "Jane",
"ClientLastName": "Doe",
"Table": [
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
},
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
]
}
]
}
问题不在于您反序列化对象的方式。您的 json 与包含 table 的两个对象不同。
第一个对象是一个 table,它有一个行数组:
"Table": {
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "2",
"BookName": "Asp.Net 4 Blue Book",
"Category": "Programming",
"Price": "56.00"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
}
你的第二个客户端对象有一个数组的数组。此外,在 table 数组之外的客户端对象中还有第二个行数组。
"Table": [
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "3",
"BookName": "Popular Science",
"Category": "Science",
"Price": "210.40"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
},
{
"Row": [
{
"BookId": "1",
"BookName": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"
},
{
"BookId": "4",
"BookName": "Mission Impossible",
"Category": "Adventure",
"Price": "210.40"
}
]
}
我建议要么以不同的方式格式化您的 json,要么创建一种不同的方法来遍历您在 json 中拥有的两种类型的 table。一个是对象,一个是数组。
例如。我将您的动态更改为 Newtonsoft.Json.Linq 中的 Newtonsoft Jobject;这将在两个 table 上出现,一个是对象,第二个是数组。
var converter = new ExpandoObjectConverter();
var deserializeObject = JsonConvert.DeserializeObject<JObject>(jsonString, converter);
foreach(var v in deserializeObject["Model"])
{
if(v["Table"] != null && v["Table"].Type == JTokenType.Object)
{
foreach (var x in v["Table"]["Row"])
{
Console.Write(x["BookId"] + " : " + x["BookName"] + Environment.NewLine);
}
}
else if (v["Table"].Type == JTokenType.Array)
{
foreach(var subTable in v["Table"])
{
foreach (var row in subTable["Row"])
{
Console.Write(row["BookId"] + " : " + row["BookName"] + Environment.NewLine);
}
}
}
}
Table
属性 在一个实例中被格式化为数组,在另一个实例中被格式化为对象。前者反序列化为List<object>
,后者反序列化为KeyValuePair<string, object>
。
您可以检查当前实例中的 Table
是否为 KeyValuePair<string, object>
类型,然后相应地进行:
foreach (var model in deserializeObject.Model)
{
foreach (var table in model.Table)
{
if(table is KeyValuePair<string, object>)
{
foreach (var row in table.Value)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
else
{
foreach (var row in table.Row)
{
Console.WriteLine(row.BookId + ": " + row.BookName);
}
}
}
}