2016-03-14 4 views
4

Я хочу знать, можно ли десериализовать объект JSON, который может быть либо объектом, либо массивом.Deserialize JSON как объект или массив с JSON.Net

Похожие на этот вопрос: Jackson deserialize object or array

Но использование Json.NET.

Пример

{ 
    "response": { 
     "status":"success", 
     // Could be either a single object or an array of objects. 
     "data": { 
      "prop":"value" 
     } 
     // OR 
     "data": [ 
      {"prop":"value"}, 
      {"prop":"value"} 
     ] 
    } 
} 
+1

http://stackoverflow.com/questions/5224697/deserializing-json-when-sometimes-array-and-sometimes-object –

ответ

2

Вы можете изменить тип свойства для «данных» в вашей модели для динамического или объекта и проверить, если это массив по времени выполнения.

Вот пример:

public class Response 
{ 
    [JsonProperty("status")] 
    public string Status { get; set; } 
    [JsonProperty("data")] 
    public dynamic Data { get; set; } 
} 


var response = JsonConvert.DeserializeJson<Response>(json); 
. 
. 
. 

Type responseDataType = response.Data.GetType(); 

if(responseDataType.IsArray) { 
    // It's an array, what to do? 
} 
else { 
    // Not an array, what's next? 
} 
2

Я думаю, что это решит вашу проблему

string jsonString= "your json string"; 
var token = JToken.Parse(jsonString); 

if (token is JArray) 
{ 
    IEnumerable<Car> cars= token.ToObject<List<Car>>(); 
} 
else if (token is JObject) 
{ 
    Car car= token.ToObject<Car>(); 
} 
2

Альтернативой было бы написать наш JsonConverter и использовать его для десериализации, чтобы мы могли работать со статическими типами после преобразования ,

class JsonDataConverter : JsonConverter 
{ 
    public override bool CanWrite { get { return false; } } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(Data); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var token = JToken.ReadFrom(reader); 

     if (token is JArray) 
      return new Data(token.Select(t => t["prop"].ToString())); 
     if (token is JObject) 
      return new Data(new[] { token["prop"].ToString() }); 
     throw new NotSupportedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

[JsonConverter(typeof(JsonDataConverter))] 
class Data:List<string> 
{ 
    public Data() : base() { } 
    public Data(IEnumerable<string> data) : base(data) { } 
} 

class Response 
{ 
    public string Status { get; set; } 
    public Data Data { get; set; } 
} 

и пример:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var inputObj = @"{ 
        'response': { 
         'status':'success', 
         // Could be either a single object or an array of objects. 
         'data': { 'prop':'value'} 

           } 
          }"; 

      var inputArray = @"{ 
        'response': { 
         'status':'success', 
         // Could be either a single object or an array of objects. 
         'data':[ 
            { 'prop':'value'}, 
            { 'prop':'value'} 
           ] 
           } 
           }"; 

      var obj = JsonConvert.DeserializeAnonymousType(inputObj, new { Response = new Response() }); 

      foreach(var prop in obj.Response.Data) 
       Console.WriteLine(prop); 

      var arr = JsonConvert.DeserializeAnonymousType(inputArray, new { Response = new Response() }); 

      foreach (var prop in arr.Response.Data) 
       Console.WriteLine(prop); 
     } 
} 
Смежные вопросы