Monthly Archives: November 2012

A date with JSON

I don’t work with JSON every day. In fact, I hadn’t used it at all until the beginning of this year, when I made REST calls to Twitter and retrieved gobs of tweets as JSON.

I’m now working on a project that contains collections of immutable C# objects, and those objects need to make their way to ActionScript. Given that ActionScript is based on ECMAScript, it seems appropriate to serialize these objects as JSON so that ActionScript might easily consume them.

During my Twitter tinkering, I was using an older version of the .NET runtime, and I had no other choice but to rely on third party libraries for JSON support, lest I roll my own. This time, I have the latest and greatest at my fingertips, and I decided to take it for a test drive.

JavaScriptSerializer started off well, for the most part. I could easily serialize any object with a single line of code:

var myObj = new MyObject(...);

var jsonText = new JavaScriptSerializer().Serialize(myObj);

It’s simple, and perfectly innocent. Deserializing, however, proved to be slightly more difficult.

var deserializedObj = new JavaScriptSerializer().Deserialize<MyObject>(jsonText);

This would have worked, but the Deserialize() method depends on the existence of a default constructor, and invokes each property setter individually. That’s fine if you’re working with mutable objects, but for concurrency concerns, I insisted my objects be immutable.

The overload of Serialize() produced the same results.

var deserializedObj = new JavaScriptSerializer().Deserialize(jsonText, typeof(MyObject));

There was one last method on the JavaScriptSerializer class that had some potential: DeserializeObject().

var objGraph = new JavaScriptSerializer().DeserializeObject(jsonText);

DeserializeObject() returned a dictionary of objects keyed by string. I added a constructor to MyObject specifically to consume it. This worked, but I wasn’t pleased with having to add a separate constructor, and I wondered what I might do if types didn’t match up properly.

I continued to capture my assumptions as unit tests, and everything seemed to be working decently … until I hit a DateTime object. I would serialize a DateTime, and it would deserialize as a DateTime four hours ahead. Something was clearly awry.

A quick google search landed me at Scott Hanselman’s post from earlier this year in which he exposed JSON’s poor support of dates, and pointed out that Json.NET does a much, much better job.

I’ve used Json.NET in the past, and so with confidence, I fired up NuGet, downloaded Json.NET, and within the span of about five minutes, was able to produce this:

var jsonText = JsonConvert.SerializeObject(myObj);

var deserializedObj = JsonConvert.DeserializeObject<MyObject>(jsonText);

And, voila! Notice how I’m providing the type? Json.NET is intelligent enough to invoke my constructor with the proper values rather than just relying on a default constructor and invoking each property.

The conclusion? I spent the better part of a day trying to work around the shortcomings of JavaScriptSerializer, and Json.NET solved all of my problems in minutes. Microsoft, take note!

Advertisements