使用 Json.NET 反序列化复杂对象
Posted
技术标签:
【中文标题】使用 Json.NET 反序列化复杂对象【英文标题】:Deserializing complex object using Json.NET 【发布时间】:2014-01-01 08:04:53 【问题描述】:我需要反序列化从 grogle maps api 返回的这个 json:
"destination_addresses": [
"Via Medaglie D'Oro, 10, 47121 Forlì FC, Italia",
"Via Torino, 20123 Milano, Italia",
"Via Guglielmo Marconi, 71, 40121 Bologna, Italia",
"Via Irnerio, 40126 Bologna, Italia"
],
"origin_addresses": [
"Via Medaglie D'Oro, 10, 47121 Forlì FC, Italia",
"Via Torino, 20123 Milano, Italia",
"Via Guglielmo Marconi, 71, 40121 Bologna, Italia",
"Via Irnerio, 40126 Bologna, Italia"
],
"rows": [
"elements": [
"distance":
"text": "1 m",
"value": 0
,
"duration":
"text": "1 min",
"value": 0
,
"status": "OK"
,
"distance":
"text": "286 km",
"value": 286281
,
"duration":
"text": "2 ore 48 min",
"value": 10083
,
"status": "OK"
,
"distance":
"text": "80,1 km",
"value": 80088
,
"duration":
"text": "1 ora 3 min",
"value": 3789
,
"status": "OK"
,
"distance":
"text": "77,6 km",
"value": 77594
,
"duration":
"text": "57 min",
"value": 3422
,
"status": "OK"
]
,
"elements": [
"distance":
"text": "288 km",
"value": 287811
,
"duration":
"text": "2 ore 48 min",
"value": 10052
,
"status": "OK"
,
"distance":
"text": "1 m",
"value": 0
,
"duration":
"text": "1 min",
"value": 0
,
"status": "OK"
,
"distance":
"text": "212 km",
"value": 212423
,
"duration":
"text": "2 ore 8 min",
"value": 7664
,
"status": "OK"
,
"distance":
"text": "218 km",
"value": 218219
,
"duration":
"text": "2 ore 9 min",
"value": 7740
,
"status": "OK"
]
,
"elements": [
"distance":
"text": "78,5 km",
"value": 78528
,
"duration":
"text": "56 min",
"value": 3346
,
"status": "OK"
,
"distance":
"text": "212 km",
"value": 212190
,
"duration":
"text": "2 ore 5 min",
"value": 7519
,
"status": "OK"
,
"distance":
"text": "1 m",
"value": 0
,
"duration":
"text": "1 min",
"value": 0
,
"status": "OK"
,
"distance":
"text": "2,0 km",
"value": 1979
,
"duration":
"text": "5 min",
"value": 316
,
"status": "OK"
]
,
"elements": [
"distance":
"text": "74,7 km",
"value": 74719
,
"duration":
"text": "55 min",
"value": 3278
,
"status": "OK"
,
"distance":
"text": "218 km",
"value": 217951
,
"duration":
"text": "2 ore 9 min",
"value": 7712
,
"status": "OK"
,
"distance":
"text": "3,8 km",
"value": 3782
,
"duration":
"text": "11 min",
"value": 671
,
"status": "OK"
,
"distance":
"text": "1 m",
"value": 0
,
"duration":
"text": "1 min",
"value": 0
,
"status": "OK"
]
],
"status": "OK"
我需要创建一个距离矩阵,所以我只对“距离”中的“值”字段感兴趣。
我试过这种方法:
DataSet data = JsonConvert.DeserializeObject<DataSet>(jsonResponse);
DataTable dataTab = data.Tables["Elements"];
foreach (DataRow elements in dataTab.Rows)
Console.WriteLine(elements["distance"]);
//Do something else here
但是 JSonConvert 返回“完成反序列化对象后在 JSON 字符串中找到的附加文本。”
【问题讨论】:
【参考方案1】:您应该反序列化为与您的数据匹配的类。您可以在http://json2csharp.com/ 生成这些类。
// use like
var rootObj = JsonConvert.DeserializeObject<RootObject>(jsonResponse);
foreach (var row in rootObj.rows)
foreach (var element in row.elements)
Console.WriteLine(element.distance.text);
// you might want to change the property names to .Net conventions
// use [JsonProperty] to let the serializer know the JSON names where needed
public class Distance
public string text get; set;
public int value get; set;
public class Duration
public string text get; set;
public int value get; set;
public class Element
public Distance distance get; set;
public Duration duration get; set;
public string status get; set;
public class Row
public List<Element> elements get; set;
public class RootObject
public List<string> destination_addresses get; set;
public List<string> origin_addresses get; set;
public List<Row> rows get; set;
public string status get; set;
【讨论】:
哇,我希望我能为那个 json2charp 的东西投票两次! ;-)【参考方案2】:我认为问题在于基于我在 Stack Overflow 上搜索到的类似问题,转换为“DataSet”。
试试这个,因为我相信它会起作用(您可能需要使用“行”而不是“元素”,但我相信使用 JObject 的方法将解决“附加文本”的主要问题。
JObject json = JsonConvert.DeserializeObject<JObject>(jsonResponse);
foreach (Dictionary<string, object> item in data["Elements"])
foreach (string val in item.Values)
Console.WriteLine(val);
【讨论】:
谢谢,"data["Elements"]"?
是什么
这是您在上面发布的数据中的 JSON 对象键名“元素”。【参考方案3】:
使用动态:
dynamic json = JsonConvert.DeserializeObject(jsonResponse);
var rowCount = json.rows.Count;
Func<dynamic, int> getElementCount = r => r.elements.Count;
var maxElements = Enumerable.Max(json.rows, getElementCount);
var matrix = new int?[rowCount, maxElements];
for(int i = 0; i < rowCount; i++)
var elements = json.rows[i].elements;
for(int j = 0; j < elements.Count; j++)
var element = elements[j];
matrix[i, j] = element.distance.value;
【讨论】:
以上是关于使用 Json.NET 反序列化复杂对象的主要内容,如果未能解决你的问题,请参考以下文章
使用 DataContractSerializer 发送反序列化的 Json.net 对象时出错