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)\/"}