在 C# 中反序列化嵌套 JSON 数组时出现问题
Problems Deserializing Nested JSON Array in C#
编辑
我注意到这得到了反对票,我想这是因为没有展示研究成果。
我看过很多堆栈溢出帖子。我找不到 JSON 这个重度嵌套的示例,该示例已通过示例访问 JSON 中存储的数据之后如何被操纵。
问题与目标
使用 restsharp,我收到了对我发出的 API 调用的 JSON 响应,但是我正在努力反序列化我收到的响应。我要使用的数据似乎是一个嵌套数组(下图)。
我的目标是将该数组的内容传递给一个变量,检查它是否已填充,获取该数组的第一项,然后将该项中的属性设置为等于我数据库中的对象。
这是我在使用当前代码时收到的错误消息。似乎我将 Hit 对象视为错误类型的对象,但是在用头撞墙几个小时后,我不完全确定为什么这对这个特定的对象不起作用 JSON结构。
当前代码
var hitresult = JsonConvert.DeserializeObject( response.Content, typeof( List<Hit> ) ) as List<Hit>;
if (hitresult.Any())
{
var address = hitresult.FirstOrDefault();
verified = true;
result = string.Format( "UDPRN: {0}", address.udprn );
location.Street1 = address.line_1;
location.Street2 = address.line_2;
location.City = address.post_town;
location.State = address.county;
location.PostalCode = address.postcode;
错误信息
An exception of type 'Newtonsoft.Json.JsonSerializationException'
occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[org.hopecorby.LocationService.Hit]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array (e.g.
[1,2,3]) or change the deserialized type so that it is a normal .NET
type (e.g. not a primitive type like integer, not a collection type
like an array or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.
Path 'result', line 1, position 10.
示例JSON
{
"result": {
"total": 2,
"limit": 10,
"page": 0,
"hits": [
{
"dependant_locality": "",
"postcode_type": "L",
"po_box": "",
"post_town": "LONDON",
"delivery_point_suffix": "1A",
"double_dependant_locality": "",
"su_organisation_indicator": " ",
"longitude": -0.127695242183412,
"department_name": "",
"district": "Westminster",
"building_name": "",
"dependant_thoroughfare": "",
"northings": 179951,
"premise": "10",
"postcode_outward": "SW1A",
"postcode_inward": "2AA",
"sub_building_name": "",
"eastings": 530047,
"postcode": "SW1A 2AA",
"country": "England",
"udprn": 23747771,
"line_3": "",
"organisation_name": "Prime Minister & First Lord Of The Treasury",
"ward": "St James's",
"county": "",
"line_1": "Prime Minister & First Lord Of The Treasury",
"building_number": "10",
"thoroughfare": "Downing Street",
"line_2": "10 Downing Street",
"latitude": 51.5035398826274
},
{
"dependant_locality": "",
"postcode_type": "S",
"po_box": "",
"post_town": "LONDON",
"delivery_point_suffix": "1B",
"double_dependant_locality": "",
"su_organisation_indicator": " ",
"longitude": -0.122624730080001,
"department_name": "",
"district": "Camden",
"building_name": "Downing Court",
"dependant_thoroughfare": "",
"northings": 182178,
"premise": "Flat 10, Downing Court",
"postcode_outward": "WC1N",
"postcode_inward": "1LX",
"sub_building_name": "Flat 10",
"eastings": 530342,
"postcode": "WC1N 1LX",
"country": "England",
"udprn": 26245117,
"line_3": "Grenville Street",
"organisation_name": "",
"ward": "Bloomsbury",
"county": "",
"line_1": "Flat 10",
"building_number": " ",
"thoroughfare": "Grenville Street",
"line_2": "Downing Court",
"latitude": 51.5234851731108
}
]
},
"code": 2000,
"message": "Success"
}
我的模型(使用 json2charp 创建)
public class Hit
{
public string dependant_locality { get; set; }
public string postcode_type { get; set; }
public string po_box { get; set; }
public string post_town { get; set; }
public string delivery_point_suffix { get; set; }
public string double_dependant_locality { get; set; }
public string su_organisation_indicator { get; set; }
public double longitude { get; set; }
public string department_name { get; set; }
public string district { get; set; }
public string building_name { get; set; }
public string dependant_thoroughfare { get; set; }
public int northings { get; set; }
public string premise { get; set; }
public string postcode_outward { get; set; }
public string postcode_inward { get; set; }
public string sub_building_name { get; set; }
public int eastings { get; set; }
public string postcode { get; set; }
public string country { get; set; }
public int udprn { get; set; }
public string line_3 { get; set; }
public string organisation_name { get; set; }
public string ward { get; set; }
public string county { get; set; }
public string line_1 { get; set; }
public string building_number { get; set; }
public string thoroughfare { get; set; }
public string line_2 { get; set; }
public double latitude { get; set; }
}
public class Result
{
public int total { get; set; }
public int limit { get; set; }
public int page { get; set; }
public List<Hit> hits { get; set; }
}
public class RootObject
{
public Result result { get; set; }
public int code { get; set; }
public string message { get; set; }
}
解串器需要一个 JSON 数组。您的 JSON 是一个包含 JSON 数组的 JSON 对象。反序列化器无法知道您希望它从 hits
数组开始工作。
您需要反序列化为 RootObject。然后您就可以将 List<Hit>
称为结果的 属性。
更新:
下面的代码应该能让您明白我的意思。我测试了这个,它对我有用,你的对象和你的 JSON.
var sr = new StreamReader(@"C:\Users\danielc\Documents\Visual Studio 2012\Projects\TestJSON\TestJSON\response.json");
string json = sr.ReadToEnd();
sr.Close();
var root = JsonConvert.DeserializeObject<RootObject>(json);
var result = root.result;
var hits = result.hits;
if (hits.Any())
{
var address = hits.FirstOrDefault();
var udprn = string.Format("UDPRN: {0}", address.udprn);
Console.WriteLine(udprn);
}
Console.Read();
编辑 我注意到这得到了反对票,我想这是因为没有展示研究成果。 我看过很多堆栈溢出帖子。我找不到 JSON 这个重度嵌套的示例,该示例已通过示例访问 JSON 中存储的数据之后如何被操纵。
问题与目标
使用 restsharp,我收到了对我发出的 API 调用的 JSON 响应,但是我正在努力反序列化我收到的响应。我要使用的数据似乎是一个嵌套数组(下图)。
我的目标是将该数组的内容传递给一个变量,检查它是否已填充,获取该数组的第一项,然后将该项中的属性设置为等于我数据库中的对象。
这是我在使用当前代码时收到的错误消息。似乎我将 Hit 对象视为错误类型的对象,但是在用头撞墙几个小时后,我不完全确定为什么这对这个特定的对象不起作用 JSON结构。
当前代码
var hitresult = JsonConvert.DeserializeObject( response.Content, typeof( List<Hit> ) ) as List<Hit>;
if (hitresult.Any())
{
var address = hitresult.FirstOrDefault();
verified = true;
result = string.Format( "UDPRN: {0}", address.udprn );
location.Street1 = address.line_1;
location.Street2 = address.line_2;
location.City = address.post_town;
location.State = address.county;
location.PostalCode = address.postcode;
错误信息
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[org.hopecorby.LocationService.Hit]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'result', line 1, position 10.
示例JSON
{
"result": {
"total": 2,
"limit": 10,
"page": 0,
"hits": [
{
"dependant_locality": "",
"postcode_type": "L",
"po_box": "",
"post_town": "LONDON",
"delivery_point_suffix": "1A",
"double_dependant_locality": "",
"su_organisation_indicator": " ",
"longitude": -0.127695242183412,
"department_name": "",
"district": "Westminster",
"building_name": "",
"dependant_thoroughfare": "",
"northings": 179951,
"premise": "10",
"postcode_outward": "SW1A",
"postcode_inward": "2AA",
"sub_building_name": "",
"eastings": 530047,
"postcode": "SW1A 2AA",
"country": "England",
"udprn": 23747771,
"line_3": "",
"organisation_name": "Prime Minister & First Lord Of The Treasury",
"ward": "St James's",
"county": "",
"line_1": "Prime Minister & First Lord Of The Treasury",
"building_number": "10",
"thoroughfare": "Downing Street",
"line_2": "10 Downing Street",
"latitude": 51.5035398826274
},
{
"dependant_locality": "",
"postcode_type": "S",
"po_box": "",
"post_town": "LONDON",
"delivery_point_suffix": "1B",
"double_dependant_locality": "",
"su_organisation_indicator": " ",
"longitude": -0.122624730080001,
"department_name": "",
"district": "Camden",
"building_name": "Downing Court",
"dependant_thoroughfare": "",
"northings": 182178,
"premise": "Flat 10, Downing Court",
"postcode_outward": "WC1N",
"postcode_inward": "1LX",
"sub_building_name": "Flat 10",
"eastings": 530342,
"postcode": "WC1N 1LX",
"country": "England",
"udprn": 26245117,
"line_3": "Grenville Street",
"organisation_name": "",
"ward": "Bloomsbury",
"county": "",
"line_1": "Flat 10",
"building_number": " ",
"thoroughfare": "Grenville Street",
"line_2": "Downing Court",
"latitude": 51.5234851731108
}
]
},
"code": 2000,
"message": "Success"
}
我的模型(使用 json2charp 创建)
public class Hit
{
public string dependant_locality { get; set; }
public string postcode_type { get; set; }
public string po_box { get; set; }
public string post_town { get; set; }
public string delivery_point_suffix { get; set; }
public string double_dependant_locality { get; set; }
public string su_organisation_indicator { get; set; }
public double longitude { get; set; }
public string department_name { get; set; }
public string district { get; set; }
public string building_name { get; set; }
public string dependant_thoroughfare { get; set; }
public int northings { get; set; }
public string premise { get; set; }
public string postcode_outward { get; set; }
public string postcode_inward { get; set; }
public string sub_building_name { get; set; }
public int eastings { get; set; }
public string postcode { get; set; }
public string country { get; set; }
public int udprn { get; set; }
public string line_3 { get; set; }
public string organisation_name { get; set; }
public string ward { get; set; }
public string county { get; set; }
public string line_1 { get; set; }
public string building_number { get; set; }
public string thoroughfare { get; set; }
public string line_2 { get; set; }
public double latitude { get; set; }
}
public class Result
{
public int total { get; set; }
public int limit { get; set; }
public int page { get; set; }
public List<Hit> hits { get; set; }
}
public class RootObject
{
public Result result { get; set; }
public int code { get; set; }
public string message { get; set; }
}
解串器需要一个 JSON 数组。您的 JSON 是一个包含 JSON 数组的 JSON 对象。反序列化器无法知道您希望它从 hits
数组开始工作。
您需要反序列化为 RootObject。然后您就可以将 List<Hit>
称为结果的 属性。
更新:
下面的代码应该能让您明白我的意思。我测试了这个,它对我有用,你的对象和你的 JSON.
var sr = new StreamReader(@"C:\Users\danielc\Documents\Visual Studio 2012\Projects\TestJSON\TestJSON\response.json");
string json = sr.ReadToEnd();
sr.Close();
var root = JsonConvert.DeserializeObject<RootObject>(json);
var result = root.result;
var hits = result.hits;
if (hits.Any())
{
var address = hits.FirstOrDefault();
var udprn = string.Format("UDPRN: {0}", address.udprn);
Console.WriteLine(udprn);
}
Console.Read();