Welcome to Part 2 of a multi-part series on JavaScript Object Notation (JSON) support in the Microsoft .NET Framework. In this article, we'll focus on the very handy JavaScriptSerializer class. You can find the other parts of this series at these locations:

  • Part 1 - An exploration of the DataContractJsonSerializer class
  • Part 2 - An exploration of the JavaScriptSerializer class
  • Part 3- JSON serialization from WCF (including a REST primer)
  • Part 4 - Using the JavaScriptConverter class to customize JSON serialization

Welcome back. In Part 1 of this series, we looked at using the DataContractJsonSerializer to dehydrate and rehydrate .NET classes into JavaScript Object Notation, also known as JSON format. In this second article in the series, we'll look at a competing class in the .NET Framework called the JavaScriptSerializer. This class, which is in the System.Web.Script.Serialization namespace and can be found in the System.Web.Extensions.dll assembly, has a somewhat checkered past. It first appeared as part of the AJAX Extensions v1.0 for ASP.NET 2.0. However, by the time the class had made its way into the .NET Framework distribution in version 3.5, it had been marked as obsolete. This meant that while the class was available for use in the current framework of the time, it was likely to disappear altogether in a future release. When we examine the class together below, you'll understand why many developers were upset by the decision to deprecate this class in favor of the WCF-oriented DataContractJsonSerializer.

The DataContractJsonSerializer has one major drawback from the vantage point of many AJAX developers. Classes that are to be serialized or deserialized must be marked with the [Serializable] attribute or the [DataContract] attribute. In addition, when using the [DataContract] attribute, each member of the class that is to be serialized or deserialized must be marked with the [DataMember] attribute. Whew! That's a lot of markup for something that should be very simple. The JavaScriptSerializer has no such restriction. And what if you want to serialize a compiled class that wasn't marked with the correct attributes at compile time? The DataContractJsonSerializer, being somewhat formal in its approach to satisfying the tenets of Service-Oriented Archicture that Microsoft espouses, makes this scenario pretty much impossible. The JavaScriptSerializer was evidently written by folks on the AJAX Extensions team who felt as my friend Harry Pierson does when he says that it's time to Retire the Tenets. I agree with Harry one hundred percent. Those SOA tenets were developed in a vacuum, in a lab. The real world is messier and dirtier than anything that happens in a lab. Things move fast in the real world and sometimes we just need our specifications to be looser so that we don't get hurt by the impacts that occur naturally in design, development and in production.

These two classes, the JavaScriptSerializer and the DataContractJsonSerializer, put the debate over the tenets into stark relief. Thankfully, Microsoft heard the cry of the AJAXers and un-obsoleted the JavaScriptSerializer in the SP1 release of the .NET Framework 3.5. Thank you, Microsoft! It just goes to show you: if you make enough noise, our friends at Microsoft will respond positively and give us what we need. Of course, we should be polite and professional in our dissent. The pen is truly mightier than the sword. Let's take a look at the JavaScriptSerializer now. For now, this class supports two instance methods of interest:

  • Serialize( object ) : string
  • Deserialize( string ) : T

Given any object, the Serialize method will convert it into a string of JSON text. Conversely, given a type paramter T and a string of JSON text, the Deserialize method will return a new instance of type T. You can think of the Deserialize method like a constructor or an object factory: the raw material of JSON text goes in, an object comes out. Let's start toying with the JavaScriptSerializer by using a provocatively-named class that looks like this:

public class Unserializable
{
 // mix it up - add a field to see
 // it serializes along with the
 // properties defined below
 public int Age;
 public int ID { get; set; }
 public string Name { get; set; }
 
 // having this default constructor is
 // really important - deserialization
 // using the JavaScriptSerializer
 // depends on its existence to
 // function properly
 public Unserializable() { }
 
 public Unserializable( int age, int id, string name)
 {
 Age = age;
 ID = id;
 Name = name;
 }
}

Notice that the aptly-named Unserializable class has no attributes, base classes or interface implementations that would make it serializable using the half dozen or so patterns that .NET has evolved over the years for such purposes. However, even though the Unserializable class doesn't appear to be serialization-friendly, the JavaScriptSerializer has no problems handling it. Check out the Dehydrate and Rehydrate methods in this code:

private static string Dehydrate( Unserializable u )
{
 var jser = new JavaScriptSerializer();
 return jser.Serialize(u);
}
 
private static Unserializable Rehydrate( string jsonText )
{
 var jser = new JavaScriptSerializer();
 return jser.DeserializeUnserializable>( jsonText );
}
 
private static void Main()
{
 // serialize a POCO that is NOT marked
 // as [Serializable] nor as [DataContract]
 // into JavaScript Object Notation (JSON)
 var u = new Unserializable( 40, 2, "Donna" );
 var jsonText = Dehydrate( u );
 
 // this will write out the following JSON text
 // {"Age":40,"ID":2,"Name":"Donna"}:
 Console.WriteLine( jsonText );
 
 // now deserialize (construct) a new object
 // from the JSON text
 var u2 = Rehydrate( jsonText );
 Console.WriteLine( "Age = {0}, ID = {1}, " + "Name = {2}", u2.Age, u2.ID, u2.Name );
}

In the Main method, serializing and deserializing the Unserializable class doesn't seem to be a problem. OK, so maybe the Unserializable class wasn't so aptly named after all. It appears that the very handy JavaScriptSerializer class does something that is extraordinary when compared to all of the other .NET Framework object serialization techniques. This little class appears to be able to serialize and deserialize Plain Old CLR Objects (POCO) without a fuss. So simple! And simple is good. I think I like this little class. I'll talk more about this class and the DataContractJsonSerializer in my next article. That's all for now. Enjoy.