2014-09-08 2 views
2

내가 소비하는 JSON API 중 하나는 쿼리에서 반환되는 결과의 수에 따라 데이터 구조가 달라지는 응답을 반환합니다. 나는 그것을 C#에서 소비하고 JSON.NET을 사용하여 응답을 역 직렬화한다. 여기 다양한 데이터 구조로 JSON을 비 직렬화

는 API에서 반환 된 JSON입니다

여러 결과 응답 :

{ 
    "response": { 
    "result": { 
     "Leads": { 
     "row": [ 
      { 
      "no": "1", 
... 
... 
... 

단일 결과 응답 :

{ 
    "response": { 
    "result": { 
     "Leads": { 
     "row": { 
      "no": "1", 
... 
... 
... 

참고 "행에서의 차이 "노드는 다중 결과의 경우 배열이고 객체 인 경우 단일 결과. 응답에서 하나 개의 결과 만있을 때

public class ZohoLeadResponseRootJson 
{ 
    public ZohoLeadResponseJson Response { get; set; } 
} 

public class ZohoLeadResponseJson 
{ 
    public ZohoLeadResultJson Result { get; set; } 
} 

public class ZohoLeadResultJson 
{ 
    public ZohoDataMultiRowJson Leads { get; set; } 
} 

public class ZohoDataMultiRowJson 
{ 
    public List<ZohoDataRowJson> Row { get; set; } 
} 

public class ZohoDataRowJson 
{ 
    public int No { get; set; } 
    ... 
} 

은 "여러 결과 응답은"아무 문제없이 직렬화 복원되어 있지만 :

는 여기에이 데이터

클래스를 직렬화하는 데 사용하는 클래스입니다 , 데이터 구조 변경 때문에 응답을 deserialize 할 수 없습니다. 예외가 발생합니다.

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON 
object (e.g. {"name":"value"}) into type 
'System.Collections.Generic.List`1[MyNamespace.ZohoDataRowJson]' 
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. 

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) 
or change the deserialized type so that it is a normal .NET type (e.g. not a 
primitive type like integer, not a collection type like an array or List<T>) 
that can be deserialized from a JSON object. JsonObjectAttribute can also be 
added to the type to force it to deserialize from a JSON object. 

Path 'response.result.Notes.row.no', line 1, position 44. 

Json.Net에서 일부 속성을 처리하고 변환기를 작성하지 않고도이 문제를 처리 할 수있는 방법이 있습니까?

+0

감사합니다 @ L.B 링크와 연결된 질문의 답. –

+0

다른 유사한 질문 http://stackoverflow.com/questions/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n –

+0

@LB ReadJson 메서드 reader.ValueType은 항상 null입니다. 이 경우에는 StartArray 또는 StartObject 인 reader.TokenType을 사용해야했습니다. 또한 두 경우 모두 deserialization이 계속됩니다. 나는 그것이 두 개의 링크 된 답변과 조금 다르기 때문에 답변을 게시하고 싶습니다. 나는 또한 미래의 사용자들이 같은 문제에 뛰어 드는 데 도움이 될 수 있도록 공급 업체의 이름을 말하고 싶습니다. –

답변

3

비슷한 질문으로 answer에서 영감을 얻었습니다.

public class ZohoDataMultiRowJson 
{ 
    [JsonConverter(typeof(ArrayOrObjectConverter<ZohoDataRowJson>))] 
    public List<ZohoDataRowJson> Row { get; set; } 
} 

public class ArrayOrObjectConverter<T> : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.StartArray) 
     { 
      return serializer.Deserialize<List<T>>(reader); 
     } 
     else if (reader.TokenType == JsonToken.StartObject) 
     { 
      return new List<T> 
      { 
       (T) serializer.Deserialize<T>(reader) 
      }; 
     } 
     else 
     { 
      throw new NotSupportedException("Unexpected JSON to deserialize"); 
     } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

* ZohoDataRowJson *뿐 아니라 대답을 좀 더 일반적인 것으로 만드는 것이 어떻습니까? 그렇게하면 완벽 할 것입니다. BTW a +1 –

+0

좋아 보인다 ... –

+0

의미가 있습니다. 업데이트 됨. +1을 가져 주셔서 감사합니다. –

관련 문제