Json.NET 获取嵌套的 jToken 值 [英] Json.NET get nested jToken value

查看:18
本文介绍了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"}]
  }}

推荐答案

可以使用SelectToken() 从 LINQ-to-JSON 层次结构的深处选择一个令牌进行反序列化.分两行:

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 []>();

或者在一行中,通过有条件地反序列化 null 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 []>();

示例小提琴.

在 c# 6 或更高版本中,使用 空条件运算符:

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() 将为错误类型的查询返回 null(例如,如果 "response" 的值 是字符串文字而不是嵌套对象),而索引运算符将抛出异常.

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.

这篇关于Json.NET 获取嵌套的 jToken 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆