2016-09-03 6 views
0

JSON.NET을 사용하여 REST API에서 응답을 역 직렬화하려고 시도하고 있습니다.JsonConvert.DeserializeObject가 null 동적 객체를 생성합니다.

dynamic resultObject = JsonConvert.DeserializeObject(responseText); 

자주 변경되므로 REST API가 반환하는 다양한 종류의 응답에 대해 클래스를 정의하지 않아도됩니다. 런타임 변수 dynamic을 활용하고 싶습니다.

VS2015에서 위의 코드 행이 실행 된 직후의 값을 보려면 감시자를 추가했습니다.

resultObject은 null object으로 해결되지만 회선 코드는 직접 실행하여 Newtonsoft.Json.Linq.JObject이되며 결과는 deserialized 응답 문자열로 채워집니다.

동적 변수 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); 
       } 

      } 

업데이트 : 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

@Evk 질문에 내용을 추가했습니다. 요청에 꽤 많은 불필요한 디버그 정보가 있습니다. 나는 그것을 제거하고 그것이 작동하는지 확인합니다. –

+1

@dbc 스크린 샷을 제거하고 최소한의 완전한 코드 샘플을 제공하도록 업데이트되었습니다. –

답변

0

에 의해 "오류"속성을 반복 한 후 JObjectJObject.Parse 사용할 수 있으며, 그 다음 줄에, 당신은 "errors""Val"라는 이름의 속성을 JSON 객체의 배열, 각이라고 가정합니다 :

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 개체로 가득 찬 코드는 디버그하기가 어려울 수도 있습니다. 대신 나는 그렇게 같이 "errors" 객체 내부의 모든 문자열 값을 선택하려면 JSONPath 재귀 하강 운영자 ..*과 함께 특별히 SelectTokens()LINQ to JSON의 사용을 권장합니다 :

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합니다.

+0

@downvoter - 이유는 무엇입니까? – dbc

1

JSonConvert는 작업을 해결할 수 없다고 생각합니다. 당신은 단순히 당신의 문제가 Item

+0

'JsonConvert.DeserializeObject()'에서'JObject.Parse()'로의 마이그레이션은 똑같은 결과로 결론지었습니다. 'JObject.Parse'의 응답에는 객체 주위에 여분의 중괄호가 있습니다. –

+0

객체를'JObject' 유형으로 선언하더라도 여전히 할당을받지 않습니다. 엄청 이상해! –

+0

객체를 빈'JObject'로 초기화 한 다음'JObject.Parse()'를 실행했습니다 - 어떻게 작동하는지는 모르겠지만 작동합니다. –

관련 문제