如何使用ServiceStack JsonSerializer序列化ExpandoObject?

时间:2011-08-21 23:12:09

标签: c# json expandoobject servicestack

是否有可能让ServiceStack JsonSerializer将ExpandoObject序列化为扁平对象而不是字典?大致与此近似的东西:

{"x":"xvalue","y":"\/Date(1313966045485)\/"}

我正在尝试使用三种不同的系统来比较ExpandoObject的JSON序列化:.NET BCL JavaScriptSerializer,Newtonsoft JSON.NET和ServiceStack的JSON产品。

我从一个相当简单的动态对象开始。

dynamic test = new ExpandoObject();
test.x = "xvalue";
test.y = DateTime.Now;

序列化程序将ExpandoObject视为IDictionary<string, object>似乎更简单。 BCL和ServiceStack都是以这种方式开始的,尽管结果与路线差别很大。

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]"]

我更喜欢将ExpandoObject序列化更多,因为它是在代码中组装的,就像典型的类会被序列化一样。你可以add an override JavaScript serializer to the BCL system for IDictionary<string, object>。这很有效,假设一个人实际上没有IDictionary<string, object>需要保持这种状态(我还没有)。

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() });
Console.WriteLine(javaScriptSerializer.Serialize(test));
// {"x":"xvalue","y":"\/Date(1313966045485)\/"}

不幸的是,我仍然需要一种方法让ServiceStack的JsonSerializer以相同的方式处理ExpandoObject。如何挂钩ServiceStack系统以实现这一目标?

更新:虽然它不是我的选择,但看起来ServiceStack处理匿名对象就好了。

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now }));
// {"x":"xvalue","y":"\/Date(1313980029620+0000)\/"}

1 个答案:

答案 0 :(得分:1)

ServiceStack的JsonSerializer中没有任何可用的钩子可以插入来改变这种行为,但是我很乐意接受执行它的拉取请求;)

您需要更改的课程是:

  • JsWriter.cs(第223行) - 插入代码以检测expando对象并返回一个委托,该委托以您希望的方式编写expando对象。
  • JsReader(第42行) - 插入代码以检测expando对象并返回委托以读取字符串的内容并将其反序列化为expando

我认为处理expando对象的代码类似于字典,所以你应该能够使用Dictionary实现类来指导你(即WriteDictionary.csDeserializeDictionary.cs

如果您对此有任何疑问/问题,请随时使用ServiceStack论坛: https://groups.google.com/forum/#!forum/servicestack