I've been a big fan of JSON.Net for the 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 the fastest framework for manipulating JSON with great documentation. This article descibes a JSON format where a list of JSON objects are present with no root elements. This would be easy if you have a root element; you could then use JObject of json.net. But in case you don't then this would throw an exception.
Let us say we have a 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 the JSON. But this can throw an error if the items in JSON have a field with incorrect value. Let's an int field have some alphabetic character. The exception will be thrown for parsing and you'll have very little details on error.
Now if you need to parse it as a list and let's say you want to find elements with fields that are not of the 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 the namespace Newtonsoft.Json.Linq to parse the data as a list of arrays of objects and then we'll convert one by one each item to a typed object and add it to the 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 an example of the preceding JSON data the last element has an invalid value to an int field major as '1AAA'.