JSON Serializers In .NET

May 22nd, 2009

I was introduced to the various serialization options in .NET while trying to build the JSON and XML filter for ASP.NET MVC. In this post I’ll take a look at the different JSON serializers in .NET and the reasons to pick one over the other.

JavaScriptSerializer

The JavaScriptSerializer lives in the System.Web.Script.Serialization namespace and the usage is fairly straight forward for serialization:

JavaScriptSerializer serializer = new JavaScriptSerializer();
String json = serializer.Serialize(data);

For deserialization however, there is a minor annoyance in that the deserializer accepts a generic type along with the content:

serializer.Deserialize<T>(String s)

which can be a problem if the type T is not known at compile time and needs to be dynamic. The work around is a bit ugly as I learnt because it uses reflection to create a generic method but it works:

var result = typeof(JavaScriptSerializer).GetMethod("Deserialize")
             .MakeGenericMethod(JsonDataType)
             .Invoke(serializer, new object[] { inputContent });

The JavaScriptSerializer is excellent for general purpose serialization and deserialization, however, one downside is that it cannot handle circular references.

A useful feature of the JavaScriptSerializer is that you can also implement a custom JavaScriptConverter and pass that in to JavaScriptSerializer for fine-grained control over the serialization/deserialization. However, for it to be really useful you need to know the types at compile time and have references to those types. This really limits the usefulness of this feature because by referencing those classes your code becomes tightly coupled so you cannot easily use it in something like an MVC filter.

The JavaScriptSerializer includes all public fields and properties for serialization by default which makes it useful when working with auto-generated classes or if you don’t have access to the source. This is different from how DataContractJsonSerializer works.

DataContractJsonSerializer

The DataContractJsonSerializer lives in the System.Runtime.Serialization.Json namespace. Unlike the JavaScriptSerializer, the DataContractJsonSerializer is a contract-based serializer so classes or members need to have the [DataContract], [DataMember] or the [Serializable] attribute.

[Serializable]
class Person {
    public String Name;
    public Int32 Age;
}

...

String json;
using (var stream = new MemoryStream()) {
    DataContractJsonSerializer serializer =
       new DataContractJsonSerializer(data.GetType());
    serializer.WriteObject(stream, data);
    json = Encoding.UTF8.GetString(stream.ToArray());
}

And for deserialization:

using(var stream = new MemoryStream(Encoding.Unicode.GetBytes(json)) {
    Object data = serializer.ReadObject(stream);
}

Since DataContractJsonSerializer is contract based and relies on attributes, it is not particularly suitable for auto-generated classes (unless they have these attributes) or when source is not accessible because the relevant attributes cannot be added at runtime as far as I know. However, for other situations attributes are an easy way to control the serialization aspects.

The most compelling feature of the DataContractJsonSerializer is that it can handle complex object graphs with circular references. This makes it particularly useful with the Entity Framework 4.0 which now support T4 templates allowing required [Serializable] or [DataMember] attributes to be added to auto-generated classes.

Json in MVC

The System.Web.Mvc namespace contains the Json function intended for use within ASP.NET MVC. There is no real reason to use it outside of ASP.NET MVC when JavaScriptSerializer and DataContractJsonSerializer are available. This function makes it extremely easy to serialize objects to a JSON string. It is not intended for deserialization, however, serialization is just one call:

String content = Json(data);

New Features in Entity Framework 4.0 (V2)

May 17th, 2009

Entity Framework 4.0 is just around the corner and it will bring some long awaited relief. I previously wrote and explained the issues around Persistence Ignorance and POCO as they apply to the Entity Framework. So obviously I’m quite excited about migrating from the interim EFPocoAdapter over to EF 4.0. Let’s take a quick look at the new features in Entity Framework 4.0.

Properties vs Fields

May 14th, 2009

There has been a lot of discussion around this topic and I only recently caught up and found some interesting gems from a variety of locations. Jon Skeet’s article Why Properties Matter is a good starting point. Robert Paulson also has a comprehensive list of pros. Summary of the pros and cons follows.

YUI Compressor for NAnt

Apr 8th, 2009

I had my first go with NAnt just a few hours ago and it was so easy, I am already porting my batch scripts over and creating build scripts with a few good examples off the web as my starting point.

Persistence Ignorance in ADO.NET Entity Framework

Apr 6th, 2009

Serializing objects within the Entity Framework is a common enough scenario that I expected to work around it farily easily. Because as it turned out, the serialized objects only contained some additional undesirable key/value pairs that I did not expect. This is when I first got introduced to Persistence Ignorance.