Wednesday, 25 September 2013

Deserialize list of json objects as list with JSON.Net

I’ve been a big fan of JSON.Net since past few years. Always helping me with less code and high performance conversion of JSON to C# objects. Thanks to James who made it possible as a fastest framework for manipulating JSON with a great documentation. In this post we will talk about a json format where a list of json objects presents with no root elements. This would be easy if you have root element you can use JObject of json.net. But in case you don’t then this would throw an exception.

Let say we have list of elements in the JSON data:

[
{
"major": 4,
"minor": 0,
"profile": "client",
"servicePack": null,
"url": "http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=5765d7a8-7722-4888-a970-ac39b33fd8ab"
},
{
"major": 4,
"minor": 0,
"profile": "full",
"servicePack": null,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=en"
},
{
"major": 3,
"minor": 5,
"profile": "client",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyId=8CEA6CD1-15BC-4664-B27D-8CEBA808B28B&displaylang=en"
},
{
"major": 3,
"minor": 5,
"profile": "full",
"servicePack": 1,
"url": "http://go.microsoft.com/fwlink/?LinkId=124150"
},
{
"major": 3,
"minor": 0,
"profile": "full",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en"
},
{
"major": 2,
"minor": 0,
"profile": "full",
"servicePack": 2,
"url": "http://www.microsoft.com/downloads/details.aspx?familyid=5B2C0358-915B-4EB5-9B1D-10E506DA9D0F&displaylang=en"
},
{
"major": 1AAA,
"minor": 1,
"profile": "full",
"servicePack": 1,
"url": "http://www.microsoft.com/downloads/details.aspx?FamilyID=a8f5654f-088e-40b2-bbdb-a83353618b38&DisplayLang=en"
}
]
// Sample taken from http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx

You can use simple Jsonconvert.Deserialize<yourType>(jsonString) to get the typed object from a JSON. But his can throw an error if the items in Json have field with incorrect value. Let’s an int field have some alphabetic character. The exception will thrown for parsing and you’ll have very little details on error.

Now if you need to parse it as list and let’s say you want to find elements who have fields which are not of correct type as it should be then we can filter them out and log them somewhere. And so you will get a complete list of correct items and corrupted data.


We’ll use a JArray class from namespace Newtonsoft.Json.Linq to parse the data as list of array of object and then we’ll convert one by one each item to typed object and add it to list. Here’s the sample generic deserializer that can parse Json and get the valid and invalid elements.


Converter/Deserializer:


public static List<string> InvalidJsonElements;

public static IList<T> DeserializeToList<T>(string jsonString)
{
InvalidJsonElements = null;
var array = JArray.Parse(jsonString);
IList<T> objectsList = new List<T>();

foreach (var item in array)
{
try
{
// CorrectElements
objectsList.Add(item.ToObject<T>());
}
catch (Exception ex)
{
InvalidJsonElements = InvalidJsonElements ?? new List<string>();
InvalidJsonElements.Add(item.ToString());
}
}

return objectsList;
}


Usage:


Product productObj = new Product();
IList<Product> validProdcuts;
IList<string> invalidProductItemInJson;
string jsonString = "[{json specified above}]";

// Call the deserializer
validProdcuts = JsonHelper.DeserializeToList<Product>(jsonString);

// Check for errors
if (JsonHelper.InvalidJsonElements.Count != 0)
{
invalidProductItemInJson = InvalidJsonElements;

// Here we have invalid items of json now we are rectified with
// the problematic data from json
}


So here you can see that you’ll have valid items in list and invalid in errors. For e.g. in the above shown JSON data the last element have invalid value to int field major as ‘1AAA’


Enjoy Jsonifying.

No comments:

Post a Comment