如何使用ServiceStack JsonSerializer序列化ExpandoObject?

是否有可能让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似乎更简单。 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的BCL系统添加覆盖JavaScript序列化程序 。 这很好用,假设一个实际上没有IDictionary需要保持这种方式(我还没有)。

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

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

您需要更改的课程是:

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

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

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