Fork on Github
Download the Nuget package
The previous tutorial focused on deserialising simple JSON objects. This tutorial describes the process of deserialising a more complex object using JSON#.
Let’s use the ComplexObject class that we’ve leveraged in earlier tutorials:
class ComplexObject : IHaveSerialisableProperties { public string Name { get; set; } public string Description { get; set; } public List<ComplexArrayObject> ComplexArrayObjects { get; set; } public List<double> Doubles { get; set; } public SerialisableProperties GetSerializableProperties() { return new SerialisableProperties("complexObject", new List<JsonProperty> { new StringJsonProperty { Key = "name", Value = Name }, new StringJsonProperty { Key = "description", Value = Description } }, new List<JsonSerialisor> { new ComplexJsonArraySerialisor("complexArrayObjects", ComplexArrayObjects.Select(c => c.GetSerializableProperties())), new JsonArraySerialisor("doubles", Doubles.Select(d => d.ToString(CultureInfo.InvariantCulture)), JsonPropertyType.Numeric) }); } }
Let’s instantiate this with some values, and serialise to JSON. I won’t bloat this post with details on how to serialise, covered in previous posts. Here is our serialised ComplexObject instance:
{"complexObject":{"name":"Complex Object","description":"A complex object","complexArrayObjects":[{"name":"Array Object #1","description":"The 1st array object"},{"name":"Array Object #2","description":"The 2nd array object"}],"doubles":[1,2.5,10.8]}}
Notice that we have 2 collections. A simple collection of Doubles
, and a more complex collection of ComplexArrayObjects
. Let’s start with those.
First, create a new class, ComplexObjectDeserialiser
, and implement the required constructor
and Deserialise
method.
Remember this method from the previous tutorial?
var properties = jsonNameValueCollection.Parse(mergeArrayValues);
This effectively parses the JSON and loads each element into a NameValueCollection
. This is fine for simple properties, however collection-based properties would cause the deserialiser to load each collection-element as a separate item in the returned NameValueCollection
, which may be somewhat cumbersome to manage:
This is where the Boolean
parameter mergeArrayValues
comes in. It will concatenate all collection-based values in a comma-delimited string, and load this value into the returned NameValueCollection
. This is much more intuitive, and allows consuming code to simply split the comma-delimited values and iterate as required.
Here is the complete code-listing:
class ComplexObjectDeserialiser : Deserialiser<ComplexObject> { public ComplexObjectDeserialiser(JsonNameValueCollection jsonNameValueCollection) : base(jsonNameValueCollection) {} public override ComplexObject Deserialise(bool mergeArrayValues = false) { var properties = jsonNameValueCollection.Parse(mergeArrayValues); var complexObject = new ComplexObject { Name = properties["complexObject.name"], Description = properties["complexObject.description"], ComplexArrayObjects = new List<ComplexArrayObject>(), Doubles = new List<double>() }; var complexArrayObjectNames = properties["complexObject.complexArrayObjects.name"].Split(','); var complexArrayObjectDescriptions = properties["complexObject.complexArrayObjects.description"].Split(','); for (var i = 0; i < complexArrayObjectNames.Length; i++) { var complexArrayObjectName = complexArrayObjectNames[i]; complexObject.ComplexArrayObjects.Add(new ComplexArrayObject { Name = complexArrayObjectName, Description = complexArrayObjectDescriptions[i] }); } var complexArrayObjectDoubles = properties["complexObject.doubles"].Split(','); foreach (var @double in complexArrayObjectDoubles) complexObject.Doubles.Add(Convert.ToDouble(@double)); return complexObject; } }
As before, we deserialise as follows:
Json.Deserialise(new ComplexObjectDeserialiser(new StandardJsonNameValueCollection("<JSON string...>")), true);
JSON# does most of the work, loading each serialised element into a NameValueCollection
. We simply read from that collection, picking and choosing each element to map to an associated POCO property.
For collection-based properties, we simply retrieve the value associated with the collection’s key, split that value into an array, and loop through the array, loading a new object for each item in the collection, building our ComplexObject
step-by-step.
This is the final JSON# post covering tutorial-based material. I’m working on a more thorough suite of performance benchmarks, and will publish the results, as well as offering a more in-depth technical analysis of JSON# in future posts. Please contact me if you would like to cover a specific topic.
The next posts will feature a tutorial series outlining Object Oriented, Test Driven Development in C# and Java. Please follow this blog to receive updates.
Connect with me: