我正在使用JSON.NET来解析JSON HTTP响应并具有工作代码,但是很确定我会以一种过于复杂的方式进行操作。我的问题是,是否有一种更直接的方法可以通过路径来使孩子jtoken和/或在不进行每个级别的情况下进行序列化。
我尝试了这种方法,但它返回null:
JObject jObj = JObject.Parse( text );
JToken myVal;
jObj.TryGetValue( "response.docs", out myVal );
这是我的工作过于复杂的代码,包括去序列化:
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 RAW响应,仅供参考:
{
"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"}]
}}
您可以使用 SelectToken()
从linq-to-json层次结构内的深处选择一个令牌。在两行中:
var token = jObj.SelectToken("response.docs");
var su = token == null ? null : token.ToObject<Solr_User []>();
或一行,当缺少选定的令牌时,通过有条件地对null JToken
进行否定:
var su = (jObj.SelectToken("response.docs") ?? JValue.CreateNull()).ToObject<Solr_User []>();
样品小提琴。
在C#6或更高版本中,使用Null条件操作员在一行中嵌套的令牌进行了更容易的序列化:
var su = jObj.SelectToken("response.docs")?.ToObject<Solr_User []>();
甚至
var su = jObj?["response"]?["docs"]?.ToObject<Solr_User []>();
请注意,SelectTokens()
比JToken
索引运算符稍微宽容,因为SelectTokens()
将返回错误类型的查询(例如,如果"response"
的值是字符串是字符串,则不是嵌套对象),而索引操作员将投掷例外。