If you have ever worked with Web APIs, you already know their importance and how much they are used in the world of web services. One of the most important part of the consumption of a Web APIs is the transformation of the response received to a format that is usable for the developer. I usually try to convert the response (a json) to an object, so that it can be used easily by the properties.
Json.NET is a very good JSON framework for .NET which you can use to serialize / deserialize the json.
Here, I am going to show you the deserialization of json to c# objects.
Suppose, you have following json object:
string json = @"{ 'id': '101', 'title': 'Parent Title', 'child': { 'childId': '201', 'childTitle': 'Child Title' } }";
To convert this json, we need to define two classes:
public class Parent { [JsonProperty("id")] public int id { get; set; } [JsonProperty("title")] public string title { get; set; } [JsonProperty("child")] public Child child { get; set; } } public class Child { [JsonProperty("childId")] public int childId { get; set; } [JsonProperty("childTitle")] public string childTitle { get; set; } }
Now, we can convert the json, like this:
var parent = JsonConvert.DeserializeObject<Parent>(json);
This is a simple case where we have a single parent object with a single child object but there could be other complex cases. Now we will take a look to some of the complex cases.
Array of Parent Objects
If, instead of a single parent object, we have an array of parent objects, each having a single child object, it can be deserialized by changing the call:
var parent = JsonConvert.DeserializeObject<List<Parent>>(json);
Array of Child Objects
Now, if the parent objects in the array also have arrays of child objects, then:
string json = @"[ { 'id': '101', 'title': 'Parent Title 1', 'child': [{ 'childId': '201', 'childTitle': 'Child Title 11' }] }, { 'id': '102', 'title': 'Parent Title 2', 'child': [ { 'childId': '201', 'childTitle': 'Child Title 21' }, { 'childId': '202', 'childTitle': 'Child Title 22' }] } ]";
To handle this case, we need to define the child as a List in the parent object.
So, instead of:
[JsonProperty("child")] public Child child { get; set; }
it should be:
[JsonProperty("child")] public List<Child> child { get; set; }
Handle both a single item and an array
Now, consider the situation where some of the objects have child arrays while others have a child object. This case cannot be handled by simply structuring your parent or child class, rather than that, you need to override JsonConverter class and need to define the child list using it.
Have a look at the json first:
string json = @"[ { 'id': '101', 'title': 'Parent Title 1', 'child': { 'childId': '201', 'childTitle': 'Child Title 11' } }, { 'id': '102', 'title': 'Parent Title 2', 'child': [ { 'childId': '201', 'childTitle': 'Child Title 21' }, { 'childId': '202', 'childTitle': 'Child Title 22' }] } ]";
Now, you need to define child list like this:
[JsonProperty("children")] [JsonConverter(typeof(ArrayOrObjectConverter<Child>))] public List<Child> children { get; set; }
And you need to override JsonConverter class like this:
public class ArrayOrObjectConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(List<T>)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JToken token = JToken.Load(reader); if (token.Type == JTokenType.Array) { return token.ToObject<List<T>>(); } return new List<T> { token.ToObject<T>() }; } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
In this way, you can convert both the object or an array of objects. However, the parent object will always contain a List of objects having one or more child objects.