json.net获得嵌套的jtoken值



我正在使用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"的值是字符串是字符串,则不是嵌套对象),而索引操作员将投掷例外。

相关内容

  • 没有找到相关文章