2017-02-17 107 views
2

我正在用Json.NET解析json http響應,並且有工作代碼,但我非常確定我正在以非常複雜的方式解決它。我的問題是,如果有一種更直接的方式來按照路徑獲得孩子jToken並且/或者將它解序列化,而不是逐級進行。Json.NET獲取嵌套的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原始響應:

{ 
    "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"}] 
    }} 

回答

1

您可以使用SelectToken()來選擇一個令牌在LINQ到JSON的層次結構中米深的反序列化:

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

樣品fiddle

在C#6或更高版本,可以使用null conditional operator

var su = jObj.SelectToken("response.docs")?.ToObject<Solr_User []>(); 

甚至

var su = jObj?["response"]?["docs"]?.ToObject<Solr_User []>(); 

注意SelectTokens()要稍微比JToken index operator更寬容,因爲SelectTokens()將返回null了查詢錯誤的類型(例如,如果"response"的值是字符串文本而不是嵌套對象),而索引運算符將拋出異常。

+0

太棒了,正是我在找的,謝謝! – edencorbin