2016-09-03 11 views
0

JSON.NETを使用してREST APIから応答を逆シリアル化しようとしています。JsonConvert.DeserializeObjectがnull動的オブジェクトを生成します

dynamic resultObject = JsonConvert.DeserializeObject(responseText); 

私はそれが頻繁に変更されるように、応答の異なる種類のREST APIの戻りのためのクラスを定義する必要はありませんしたいと思います。私はdynamicランタイム変数を利用したいと思います。

VS2015では、上記のコード行が実行された直後の値を確認するためにウォッチャーを追加しました。

resultObjectはnullになりますが、ウォッチャーでは、実行されたラインコードが直接的にNewtonsoft.Json.Linq.JObjectになり、デシリアライズされた応答文字列が設定されていることがわかります。

なぜ動的変数resultObjectにはJObjectが設定されていませんか?

  var responseStream = e.Response?.GetResponseStream(); 
      string responseText = ""; 

      if (responseStream != null) 
      { 
       using (var reader = new StreamReader(responseStream)) 
       { 
        responseText = reader.ReadToEnd(); 
       } 

       dynamic responseObject = JsonConvert.DeserializeObject(responseText); 

       foreach (var error in responseObject["errors"].Children()) 
       { 
        errors.Add(error.Val); 
       } 

      } 

UPDATE:解析するJSONの

内容:デバッグ情報を削除するように更新

JSON - 問題が解決しません。

https://jsonblob.com/57cb00c7e4b0dc55a4f2abe9

UPDATE 2:

JsonConvert.DeserializeObject()は、オブジェクト全体の周りに余分な括弧を持っている私のJSONを解析していることが表示されます。

それが応答ストリームから生成される文字列:JsonConvert.DeserializeObjectの

"{\"message\":\"422 Unprocessable Entity\",\"errors\":[[\"The email must be a valid email address.\"],[\"The password must be at least 8 characters.\"]],\"status_code\":422}"

値():

{{ "message": "422 Unprocessable Entity", "errors": [ [ "The email must be a valid email address." ], [ "The password must be at least 8 characters." ] ], "status_code": 422 }}

UPDATE 3: が生じJObject.Parseへの変換同じ出力です。

変数をタイプdynamicからJObjectに変更しました - JObject.Parse()からの応答を受け入れるために、変数はnullに設定されています。

+0

レスポンスのテキストは何ですか?単純なjsonオブジェクトでは、動的オブジェクトのプロパティをうまく取得できます。 – Evk

+0

@エヴァーク質問に内容を追加しました。要求にはかなりの不必要なデバッグ情報があります。私はそれを削除し、それが動作するかどうかを確認します。 –

+1

@dbcスクリーンショットを削除し、最小限の完全なコードサンプルを提供するように更新されました。 –

答えて

0

で「エラー」プロパティを反復処理し、その後JObjectJObject.Parseを使用してすることができます:

foreach (var error in responseObject["errors"].Children()) 
{ 
    errors.Add(error.Val); 
} 

しかし、"errors"は実際配列の配列であるのでerror.Valnullに評価します。代わりに、あなたのような何かをする必要があります。

var errors = new List<string>(); 

dynamic responseObject = JsonConvert.DeserializeObject(responseText); 

foreach (dynamic errorList in responseObject["errors"].Children()) 
{ 
    foreach (dynamic error in errorList.Children()) 
    { 
     errors.Add((string)error); 
    } 
} 

個人的に、あなたは、静的な、コンパイル時の型チェックの利点を失うので、しかし、私はdynamicの使用を避けることをお勧めします。 dynamicオブジェクトがいっぱいのコードもデバッグが難しい場合があります。

var token = JToken.Parse(responseText); 

var errors = token.SelectTokens("errors..*") // Iterate through all descendants of the "errors" property 
    .OfType<JValue>()       // Filter those that are primitive values 
    .Select(v => (string)v)      // Convert to their string values 
    .ToList();         // And evaluate the query as a list. 

fiddle:代わりに、私はそうのような"errors"オブジェクト内のすべての文字列値を選び出すために、JSONPath再帰下降演算子..*とともに、具体的SelectTokens()LINQ to JSONの使用をお勧めします。

+0

@downvoter - 理由を教えてください。 – dbc

1

JSonConvertはあなたの仕事を解決するためには無効だと思います。あなたは、単にあなたの問題は、次の行では、あなたが"Val"という名前のプロパティを持つ各、"errors"オブジェクト JSONの配列であると仮定されている、ということであるItem

+0

'JsonConvert.DeserializeObject()'から 'JObject.Parse()'への移行はまったく同じ結果で終了しました。 'JObject.Parse'からの応答には、オブジェクトの周りに余分な中カッコがあります。 –

+0

オブジェクトが 'JObject'型であると宣言しても、依然として代入を受け付けません。非常に奇妙な! –

+0

空の 'JObject'にオブジェクトを初期化し、' JObject.Parse() 'を実行しました - それは動作するとは思われませんが、動作します。 –

関連する問題