2012-06-03 2 views
1

У меня есть ситуация, когда API, который я использую, возвращает несогласованный JSON, который я хочу десериализовать с помощью JSON.NET. В одном случае, он возвращает объект, который содержит объекты (обратите внимание, что внешние «1» может быть любое количество):JSON.NET Deserialize объектов в объекте/массиве объектов

{ 
    "1":{ 
     "0":{ 
     "db_id":"12835424", 
     "title":"XXX" 
     }, 
     "1":{ 
     "db_id":"12768978", 
     "title":"YYY" 
     }, 
     "2":{ 
     "db_id":"12768980", 
     "title":"ZZZ" 
     }, 
     "3":{ 
     "db_id":"12768981", 
     "title":"PPP" 
     } 
    } 
} 

И в другом случае, он возвращает массив объектов:

{ 
    "3":[ 
     { 
     "db_id":"12769199", 
     "title":"XXX" 
     }, 
     { 
     "db_id":"12769200", 
     "title":"YYY" 
     }, 
     { 
     "db_id":"12769202", 
     "title":"ZZZ" 
     }, 
     { 
     "db_id":"12769243", 
     "title":"PPP" 
     } 
    ] 
} 

Я понятия не имею, почему эта несогласованность существует, но это формат, с которым я работаю. Каким будет правильный способ десериализации обоих форматов с помощью метода JsonConvert.DeserializeObject?

ответ

11

С текущей версии Json.NET (Json.NET 4,5 Release 11), вот CustomCreationConverter, который будет обрабатывать JSon что десериализует иногда как объект, а иногда в виде массива ,

public class ObjectToArrayConverter<T> : CustomCreationConverter<List<T>> where T : new() 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     List<T> target = new List<T>(); 

     try 
     { 
      // Load JObject from stream 
      JArray jArray = JArray.Load(reader); 

      // Populate the object properties 
      serializer.Populate(jArray.CreateReader(), target); 
     } 
     catch (JsonReaderException) 
     { 
      // Handle case when object is not an array... 

      // Load JObject from stream 
      JObject jObject = JObject.Load(reader); 

      // Create target object based on JObject 
      T t = new T(); 

      // Populate the object properties 
      serializer.Populate(jObject.CreateReader(), t); 

      target.Add(t); 
     } 

     return target; 
    } 

    public override List<T> Create(Type objectType) 
    { 
     return new List<T>(); 
    } 
} 

Пример:

[JsonObject] 
public class Project 
{ 
    [JsonProperty] 
    public string id { get; set; } 

    // The Json for this property sometimes comes in as an array of task objects, 
    // and sometimes it is just a single task object. 
    [JsonProperty] 
    [JsonConverter(typeof(ObjectToArrayConverter<Task>))] 
    public List<Task> tasks{ get; set; } 
} 

[JsonObject] 
public class Task 
{ 
    [JsonProperty] 
    public string name { get; set; } 

    [JsonProperty] 
    public DateTime due { get; set; } 
} 
Смежные вопросы