2017-02-17 23 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 []>(); 

サンプルfiddleSelectTokens()SelectTokens()がためにnullを返しますよう、JToken index operatorよりもわずかに寛容であることを

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

あるいは

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

注:

C#6で

以降、あなたはnull conditional operatorを使用することができます間違った型のクエリ(例えば、"response"の値がネストされたオブジェクトではなく文字列リテラルであった場合)、インデックス演算子は例外をスローします。

+0

素晴らしいと私が探していたもの、ありがとう! – edencorbin

関連する問題