Json.NET获取嵌套的jToken值
我正在使用Json.NET解析json http响应,并且具有正常工作的代码,但是可以肯定的是,我将以一种过于复杂的方式进行处理.我的问题是,是否有更直接的方法可以通过路径获取子jToken和/或反序列化它,而无需遍历每个级别.
I am working at parsing a json http response with Json.NET and have working code, but am pretty sure I am going about it in an overly complicated way. My question is if there is a more direct way to get a child jToken by path and/or de-serialize it without foreaching every level.
我尝试了这种方法,但是它返回null:
I tried this approach but it returns null:
JObject jObj = JObject.Parse( text );
JToken myVal;
jObj.TryGetValue( "response.docs", out myVal );
这是我工作过于复杂的代码,包括反序列化:
Here is my working overly complicated code, including de-serialization:
JObject jObj = JObject.Parse( text );
foreach( var kv in jObj ) {
if( kv.Key == "response" ) {
foreach( JToken jt in kv.Value ) {
if( jt.Path == "response.docs" ) {
JEnumerable<JToken> children = jt.Children();
foreach( JToken t in children ) {
//THIS WORKS BUT IS NOT ELEGANT
Solr_User[] su = t.ToObject<Solr_User[]>();
}
}
}
}
}
这是JSON原始响应,仅供参考:
And here is the JSON raw response just for reference:
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"*:*",
"indent":"on",
"wt":"json"}},
"response":{"numFound":4,"start":0,"docs":[
{
"id":3,
"first_name":"Bob",
"_version_":"1558902640594649088"},
{
"id":4,
"first_name":"Sam",
"_version_":"1558902640613523456"},
{
"id":2,
"first_name":"Fred",
"_version_":"1558902640613523457"},
{
"id":1,
"first_name":"Max",
"_version_":"1558902640613523458"}]
}}
You can use SelectToken()
to select a token from deep within the LINQ-to-JSON hierarchy for deserialization. In two lines:
var token = jObj.SelectToken("response.docs");
var su = token == null ? null : token.ToObject<Solr_User []>();
或者在一行中,当缺少所选令牌时,有条件地反序列化空JToken
:
Or in one line, by conditionally deserializing a null JToken
when the selected token is missing:
var su = (jObj.SelectToken("response.docs") ?? JValue.CreateNull()).ToObject<Solr_User []>();
样本小提琴.
In c# 6 or later it's even easier to deserialize a nested token in one line using the null conditional operator:
var su = jObj.SelectToken("response.docs")?.ToObject<Solr_User []>();
甚至
var su = jObj?["response"]?["docs"]?.ToObject<Solr_User []>();
请注意,SelectTokens()
比 JToken
索引稍微宽容,因为SelectTokens()
对于错误类型的查询(例如,如果"response"
的值是字符串文字而不是嵌套对象)将返回null,而索引运算符将引发异常.
Note that SelectTokens()
is slightly more forgiving than the JToken
index operator, as SelectTokens()
will return null for a query of the wrong type (e.g. if the value of "response"
were a string literal not a nested object) while the index operator will throw an exception.