6

是否可以让 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 更多地序列化,因为它是在代码中组装的,就像一个典型的类会被序列化一样。您可以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)\/"}
4

1 回答 1

1

ServiceStack 的 JsonSerializer 中没有任何可用的钩子可供您插入以更改此行为,但我很乐意接受一个拉取请求来做到这一点;)

您需要更改的课程是:

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

我想处理扩展对象的代码类似于字典,因此您应该能够使用 Dictionary 实现类来指导您(即WriteDictionary.csDeserializeDictionary.cs

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

于 2011-08-22T04:25:56.020 回答