Deserialize JSON as an object or array with JSON.Net

I want to know if it is possible to deserialize a JSON object, which can be either an object or an array.

Similar to this question: Jackson deserializes an object or array

But using JSON.Net.

Example

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

You can change the property type for "data" in your model to dynamic or an object and check if it is an array at run time.

Here is an example:

 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 an array, what to do? } else { // Not an array, what next? } 
+2
source

An alternative would be to write our JsonConverter and use it for deserialization so that we can work with static types after conversion.

 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; } } 

and example:

  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); } } 
+3
source

I think this solves your problem

 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
source

Source: https://habr.com/ru/post/1244984/


All Articles