Aug 22, 2010

Deserializing JSON to anonymous types in C#

C#, development

I think dynamic languages have some serious advantages when working with JSON over static languages. Things are just easier and there is a lot less friction. Static languages like C# make things a little cumbersome because you always need to specify a type. That is almost always. :) There is an alternative in C#, provided via anonymous types. You can deserialize to an anonymous type by giving the JSON deserializer and example object. (I’m using the fabulous JSON.net library for these samples) Let’s see what I mean:

public class JSON_to_anonymous_type
{
private string json = @"{ Name: ""James"" }";

[Test]
public void can_deserialize_to_simple_anonymous_type()
{
var example = new { Name = string.Empty };
var person = JsonConvert.DeserializeAnonymousType(json, example);

Assert.AreEqual("James", person.Name);
}
}

The JSON serializer will take your example anonymous object and attempt to use it as template to deserialize the JSON literal. This provides a nice alternative to defining a full blown C# class to deserialize to in some cases.

The example above is rather simplistic, usually the JSON literals we have to deal with in real life are a little more complex than this. Let’s look at something a little closer to a real life scenario. Say the person is married, and we’d like to include the spouse information with our JSON literal. We now need a nested anonymous type. The syntax can get a little crazy but here goes:

public class JSON_to_anonymous_type
{
private string json_moderate = @"{ Name: ""James"", Spouse : { Name: ""Sally""} }";
[Test]
public void can_deserialize_to_moderately_complex_anonymous_type()
{
var example = new { Name = string.Empty, Spouse = new { Name = string.Empty } };
var person = JsonConvert.DeserializeAnonymousType(json_moderate, example);

Assert.AreEqual("James", person.Name);
Assert.AreEqual("Sally", person.Spouse.Name);
}
}

Let’s try one more scenario – we would like to parse a list of children from the JSON literal. This is starting to become a little hard to read, but still better than having to define two static classes if all we need to do is say count the couple’s children.

public class JSON_to_anonymous_type
{
private string json_complex = @"{ Name: ""James"", Spouse : { Name: ""Sally""}, Children : [ { Name : ""Tom"" }, { Name : ""Sandra"" } ] }";

[Test]
public void can_deserialize_to_complex_anonymous_type()
{
var example = new { Name = string.Empty, Spouse = new { Name = string.Empty }, Children = new[] { new { Name = string.Empty }}};
var person = JsonConvert.DeserializeAnonymousType(json_complex, example);

Assert.AreEqual("James", person.Name);
Assert.AreEqual("Sally", person.Spouse.Name);
Assert.AreEqual(2, person.Children.Length);
}
}

I think that covers a couple of complex scenarios that you might encounter in real life. Deserializing to anonymous types can reduce the friction of declaring one or more static classes for simple scenarios where we may need to simply peak at a JSON literal to extract one or two properties, or perform some simple operation. If things get a little more serious than by all means declare a couple of static types to deserialize to, if only for readability's sake.