2014-09-08 2 views
2

Один из API JSON, который я потребляю, возвращает ответ, который меняет структуру данных в зависимости от того, сколько результатов возвращается из запроса. Я потребляю его из C# и используя JSON.NET для десериализации ответа.Deserialize JSON с переменной структурой данных

Вот JSON, который возвращается из API

Multiple Результат Ответ:

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

Single Результат Ответ:

{ 
    "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; } 
    ... 
} 

«Multiple Результат ответа» десериализируется без каких-либо проблем, но когда есть только один результат в ответе , из-за изменения структуры данных ответ не может быть десериализован. Я получаю исключение

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

@ФУНТ в ReadJson reader.ValueType всегда null. В этом случае мне пришлось использовать reader.TokenType, который является StartArray или StartObject. Кроме того, в обоих случаях десериализация будет продолжаться. Я хотел бы опубликовать ответ, поскольку он немного отличается от обоих связанных ответов. Я также хотел бы назвать поставщика, чтобы это могло помочь будущим пользователям работать в одной и той же проблеме. –

ответ

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. –

Смежные вопросы