Json.NET 获取嵌套的 jToken 值

ede*_*bin 6 json.net

我正在使用 Json.NET 解析 json http 响应并有工作代码,但我很确定我正在以一种过于复杂的方式进行处理。我的问题是是否有更直接的方法来通过路径获取子 jToken 和/或反序列化它而不用 foreaching 每个级别。

我试过这种方法,但它返回空值:

  JObject jObj = JObject.Parse( text );
  JToken myVal;
  jObj.TryGetValue( "response.docs", out myVal );
Run Code Online (Sandbox Code Playgroud)

这是我的工作过于复杂的代码,包括反序列化:

  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[]>();
          }
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

这是 JSON 原始响应,仅供参考:

{
  "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"}]
  }}
Run Code Online (Sandbox Code Playgroud)

dbc*_*dbc 8

您可以使用SelectToken()从 LINQ-to-JSON 层次结构的深处选择令牌以进行反序列化。在两行中:

var token = jObj.SelectToken("response.docs");
var su = token == null ? null : token.ToObject<Solr_User []>();
Run Code Online (Sandbox Code Playgroud)

或者在一行中,通过在缺少所选标记时有条件地反序列化nullJToken

var su = (jObj.SelectToken("response.docs") ?? JValue.CreateNull()).ToObject<Solr_User []>();
Run Code Online (Sandbox Code Playgroud)

样品小提琴

在 c# 6 或更高版本中,使用空条件运算符反序列化一行中的嵌套标记更容易:

var su = jObj.SelectToken("response.docs")?.ToObject<Solr_User []>();
Run Code Online (Sandbox Code Playgroud)

甚至

var su = jObj?["response"]?["docs"]?.ToObject<Solr_User []>();
Run Code Online (Sandbox Code Playgroud)

请注意,SelectTokens()它比JToken索引运算符稍微宽容一些,因为SelectTokens()对于错误类型的查询(例如,如果 的值"response"是字符串文字而不是嵌套对象),它将返回 null,而索引运算符将引发异常。