如何在 C# 中使用 JSON.Net 查询和枚举复杂的 JSON 对象
How to Query and Enumerate complex JSON object using JSON.Net in C#
如何使用 JSON.NET 在 C# 中 ?
我从 API 接收到一个复杂的 JSON 对象,该对象的属性变量为 number/type。
我一直在阅读 the JSON.Net Documentation、审查示例等,但没有深入了解 JObject、JArray、JToken、使用动态等...
我想找到 pageResponses.scriptOutput
属性,验证它包含 .items[]
数组,然后 enumerate/iterate 数组。
编辑
我取得了进步,但在 JSON 数据示例中发现了拼写错误。
但是我如何 query/enumerate 使用键名的子对象,例如 (item.location, item.timestamp
) ?
string json = File.ReadAllText(@"Output.json");
JObject jObj = JObject.Parse(json);
IList<JToken> items = jObj["pageResponses"][0]["scriptOutput"]["items"].ToList();
foreach (JToken item in items){
Console.WriteLine(item["location"]);
}
/*** Console Output ***/
// Austin, TX
// Anaheim, CA
// Adams, MN
// Barstow, CA
var varItems = from o in jObj["pageResponses"][0]["scriptOutput"]["items"].ToList() select o;
foreach (var item in varItems){
Console.WriteLine(item["timestamp"]);
}
/*** Console Output ***/
// 2016 - 05 - 03 19:53
// 2016 - 05 - 04 04:10
// 2016 - 05 - 04 08:18
// 2016 - 05 - 01 12:26
(JSON 为简洁起见,下面的示例被删减了)
{
"meta": {
"outputAsJson": true,
"backend": {
"os": "linux",
"id": "10.240.0.3_2",
"requestsProcessed": 8
}
},
"pageResponses": [
{
"pageRequest": {
"renderType": "script",
"outputAsJson": true
},
"frameData": {
"name": "",
"childCount": 1
},
"events": [
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:30.344Z"
},
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:31.131Z"
}
],
"scriptOutput": {
"items": [
{
"location": "Austin, TX",
"timestamp": "2016-05-03 19:53",
"title": "User Login"
},
{
"location": "Anaheim, CA",
"timestamp": "2016-05-04 04:10",
"title": "User Logout"
},
{
"location": "Adams, MN",
"timestamp": "2016-05-04 08:18",
"title": "User Login"
},
{
"location": "Barstow, CA",
"timestamp": "2016-05-01 12:26",
"title": "User Logout"
}
]
},
"statusCode": 200
}
],
"statusCode": 200,
"content": {
"name": "content.json",
"encoding": "utf8"
},
"originalRequest": {
"pages": [
{
"renderType": "script",
"outputAsJson": true
}
]
}
}
我建议创建一个代理 class(我使用 json2csharp):
public class Backend
{
public string os { get; set; }
public string id { get; set; }
public int requestsProcessed { get; set; }
}
public class Meta
{
public bool outputAsJson { get; set; }
public Backend backend { get; set; }
}
public class PageRequest
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class FrameData
{
public string name { get; set; }
public int childCount { get; set; }
}
public class Event
{
public string key { get; set; }
public string time { get; set; }
}
public class ScriptOutput
{
public List<object> items { get; set; }
}
public class PageRespons
{
public PageRequest pageRequest { get; set; }
public FrameData frameData { get; set; }
public List<Event> events { get; set; }
public ScriptOutput scriptOutput { get; set; }
public int statusCode { get; set; }
}
public class Content
{
public string name { get; set; }
public string encoding { get; set; }
}
public class Page
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class OriginalRequest
{
public List<Page> pages { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public List<PageRespons> pageResponses { get; set; }
public int statusCode { get; set; }
public Content content { get; set; }
public OriginalRequest originalRequest { get; set; }
}
然后反序列化:
var obj = JsonConvert.DeserializeObject<RootObject>(json);
if (obj != null && obj.pageResponses != null)
{
foreach (var pageResponse in obj.pageResponses)
{
if (pageResponse.scriptOutput == null)
continue;
foreach (var item in pageResponse.scriptOutput.items)
{
Console.WriteLine(item);
}
}
}
我用几个扩展方法来做到这一点,我使用 JsonConvert.DeserializeObject。
下面的代码片段。
用法
ExpandoObject data = JsonConvert.DeserializeObject<ExpandoObject>(jsonString);
if(data.HasProperty("propertyToCheck"))
{
object[] objects = data.Get<object[]>("propertyToCheck");
}
在上面的代码片段中,我检查了一个 属性 是否存在,然后我将它分配给一个 .Net 类型,在本例中是一个对象数组。虽然它可以是任何类型,只要它是理智的。
扩展方法
public static bool HasProperty(this ExpandoObject value, string property)
{
bool hasProp = false;
if (((IDictionary<String, object>)value).ContainsKey(property))
{
hasProp = true;
}
return hasProp;
}
public static T Get<T>(this ExpandoObject value, string property)
{
return (T)((IDictionary<String, dynamic>)value)[property];
}
快速、简单、切中要点!
如何使用 JSON.NET 在 C# 中 ?
我从 API 接收到一个复杂的 JSON 对象,该对象的属性变量为 number/type。
我一直在阅读 the JSON.Net Documentation、审查示例等,但没有深入了解 JObject、JArray、JToken、使用动态等...
我想找到 pageResponses.scriptOutput
属性,验证它包含 .items[]
数组,然后 enumerate/iterate 数组。
编辑
我取得了进步,但在 JSON 数据示例中发现了拼写错误。
但是我如何 query/enumerate 使用键名的子对象,例如 (item.location, item.timestamp
) ?
string json = File.ReadAllText(@"Output.json");
JObject jObj = JObject.Parse(json);
IList<JToken> items = jObj["pageResponses"][0]["scriptOutput"]["items"].ToList();
foreach (JToken item in items){
Console.WriteLine(item["location"]);
}
/*** Console Output ***/
// Austin, TX
// Anaheim, CA
// Adams, MN
// Barstow, CA
var varItems = from o in jObj["pageResponses"][0]["scriptOutput"]["items"].ToList() select o;
foreach (var item in varItems){
Console.WriteLine(item["timestamp"]);
}
/*** Console Output ***/
// 2016 - 05 - 03 19:53
// 2016 - 05 - 04 04:10
// 2016 - 05 - 04 08:18
// 2016 - 05 - 01 12:26
(JSON 为简洁起见,下面的示例被删减了)
{
"meta": {
"outputAsJson": true,
"backend": {
"os": "linux",
"id": "10.240.0.3_2",
"requestsProcessed": 8
}
},
"pageResponses": [
{
"pageRequest": {
"renderType": "script",
"outputAsJson": true
},
"frameData": {
"name": "",
"childCount": 1
},
"events": [
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:30.344Z"
},
{
"key": "navigationRequested",
"time": "2016-05-06T13:43:31.131Z"
}
],
"scriptOutput": {
"items": [
{
"location": "Austin, TX",
"timestamp": "2016-05-03 19:53",
"title": "User Login"
},
{
"location": "Anaheim, CA",
"timestamp": "2016-05-04 04:10",
"title": "User Logout"
},
{
"location": "Adams, MN",
"timestamp": "2016-05-04 08:18",
"title": "User Login"
},
{
"location": "Barstow, CA",
"timestamp": "2016-05-01 12:26",
"title": "User Logout"
}
]
},
"statusCode": 200
}
],
"statusCode": 200,
"content": {
"name": "content.json",
"encoding": "utf8"
},
"originalRequest": {
"pages": [
{
"renderType": "script",
"outputAsJson": true
}
]
}
}
我建议创建一个代理 class(我使用 json2csharp):
public class Backend
{
public string os { get; set; }
public string id { get; set; }
public int requestsProcessed { get; set; }
}
public class Meta
{
public bool outputAsJson { get; set; }
public Backend backend { get; set; }
}
public class PageRequest
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class FrameData
{
public string name { get; set; }
public int childCount { get; set; }
}
public class Event
{
public string key { get; set; }
public string time { get; set; }
}
public class ScriptOutput
{
public List<object> items { get; set; }
}
public class PageRespons
{
public PageRequest pageRequest { get; set; }
public FrameData frameData { get; set; }
public List<Event> events { get; set; }
public ScriptOutput scriptOutput { get; set; }
public int statusCode { get; set; }
}
public class Content
{
public string name { get; set; }
public string encoding { get; set; }
}
public class Page
{
public string renderType { get; set; }
public bool outputAsJson { get; set; }
}
public class OriginalRequest
{
public List<Page> pages { get; set; }
}
public class RootObject
{
public Meta meta { get; set; }
public List<PageRespons> pageResponses { get; set; }
public int statusCode { get; set; }
public Content content { get; set; }
public OriginalRequest originalRequest { get; set; }
}
然后反序列化:
var obj = JsonConvert.DeserializeObject<RootObject>(json);
if (obj != null && obj.pageResponses != null)
{
foreach (var pageResponse in obj.pageResponses)
{
if (pageResponse.scriptOutput == null)
continue;
foreach (var item in pageResponse.scriptOutput.items)
{
Console.WriteLine(item);
}
}
}
我用几个扩展方法来做到这一点,我使用 JsonConvert.DeserializeObject。
下面的代码片段。
用法
ExpandoObject data = JsonConvert.DeserializeObject<ExpandoObject>(jsonString);
if(data.HasProperty("propertyToCheck"))
{
object[] objects = data.Get<object[]>("propertyToCheck");
}
在上面的代码片段中,我检查了一个 属性 是否存在,然后我将它分配给一个 .Net 类型,在本例中是一个对象数组。虽然它可以是任何类型,只要它是理智的。
扩展方法
public static bool HasProperty(this ExpandoObject value, string property)
{
bool hasProp = false;
if (((IDictionary<String, object>)value).ContainsKey(property))
{
hasProp = true;
}
return hasProp;
}
public static T Get<T>(this ExpandoObject value, string property)
{
return (T)((IDictionary<String, dynamic>)value)[property];
}
快速、简单、切中要点!