JSON Entity Converter
Whether in the context of my friend Curtis’s BORAX proposal, or my own, we will eventually need to serialize our domain objects and ship them to the browser.
Our best solutions is probably some sort of Domain Transfer Object (DTO), but for a second let’s assume we take the quick route and turn our domain objects directly into JSON mush.
Is ASP.NET MVC 3 we can use the JsonResult class, but with it comes a problem:
the JavaScriptSerializer, which JsonResult
uses,
cannot handle circular references (and rightfully so since JSON doesn’t have references).
Let me illustrate using the following simplified domain classes (you can find the full code in this Gist):
When serializing an object of type Company
, the JavaScriptSerializer
will choke on Contact.WorksFor
since it points back to the Company
that the contact is associated with.
Before we talk about how we’ll fix it, let’s talk about the output. What I think I’d like to have when serialize a company to JSON is:
In other words, if one of the object we try to serialize has
a property of type Entity
, we’ll just output its Id
and assume the consumer of the JSON will
know to request /refdata/{entitytypes}/{id}
to resolve it, if needed.
Of course, this will not avoid circular references entirely, but merely provide an example on how to work with the class that will solve our particular problem: JavaScriptConverter.
JavaScriptConverter
, of the System.Web.Script.Serialization
clan, allows us to inject specific
type handlers into JavaScriptSerializer
and
have it defer to our converter when encountering those types in the serialization process.
And it gets better: our converter won’t have to provide actual JSON, it merely has to
return a dictionary of name-value pairs and the JavaScriptSerializer
will take care
of the actual transformation.
Here’s how we could implement the required Serialize
method:
(Of course the actual implementation is a bit more elegant, I hope)
We can now serialize objects such as these:
And get the following JSON representation:
The full code - designed to work with the most excellect LINQPad,
shows three attempts (four if we include the failed circular reference error)
and with them the various ways the EntityConverter
can control the JSON output.
If you want to use the code in Visual Studio, add a reference to System.Web.Extensions
and import the System.Web.Script.Serialization
namespace.