Is it possible to get the ServiceStack JsonSerializer to serialize an ExpandoObject as a flat object rather than a dictionary? Something roughly approximate to this:
{"x":"xvalue","y":"\/Date(1313966045485)\/"}
I am trying to compare JSON serialization of ExpandoObject
using three different systems: the .NET BCL JavaScriptSerializer, Newtonsoft JSON.NET, and ServiceStack's JSON offering.
I start with a fairly simple dynamic object.
dynamic test = new ExpandoObject();
test.x = "xvalue";
test.y = DateTime.Now;
It seems simpler for a serializer to treat an ExpandoObject as a IDictionary<string, object>
. Both BCL and ServiceStack start off this way, though going fairly different routes with the result.
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
Console.WriteLine(javaScriptSerializer.Serialize(test));
// [{"Key":"x","Value":"xvalue"},{"Key":"y","Value":"\/Date(1313966045485)\/"}]
Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(test));
// ["[x, xvalue]","[y, 8/21/2011 16:59:34 PM]"]
I would prefer to have ExpandoObject serialized more as it is assembled in code, like a typical class would be serialized. You can add an override JavaScript serializer to the BCL system for IDictionary<string, object>
. This works great, assuming one doesn't actually have a IDictionary<string, object>
that needs to stay that way (which I don't yet).
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() });
Console.WriteLine(javaScriptSerializer.Serialize(test));
// {"x":"xvalue","y":"\/Date(1313966045485)\/"}
Unfortunately, I still need a way to get ServiceStack's JsonSerializer to treat an ExpandoObject in the same fashion. How do I hook into the ServiceStack system to make this possible?
Update: While it isn't an option for my uses, it looks like ServiceStack handles anonymous objects just fine.
Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now }));
// {"x":"xvalue","y":"\/Date(1313980029620+0000)\/"}
There aren't any hooks available in ServiceStack's JsonSerializer that you can plug into to change this behaviour but I'm be more than happy to take a pull request that does it ;)
The classes you will need to change are:
I imagine the code for dealing with an expando object is similar to a dictionary so you should be able to use the Dictionary implementation classes to guide you (i.e. WriteDictionary.cs and DeserializeDictionary.cs)
Feel free to use the ServiceStack forum if you have any more questions/issues on this: https://groups.google.com/forum/#!forum/servicestack