如何使用 ServiceStack JsonSerializer 序列化 ExpandoObject?

Posted

技术标签:

【中文标题】如何使用 ServiceStack JsonSerializer 序列化 ExpandoObject?【英文标题】:How to serialize ExpandoObject using ServiceStack JsonSerializer? 【发布时间】:2011-10-31 18:57:00 【问题描述】:

是否可以让 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】:

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

您需要更改的类是:

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

我认为处理 expando 对象的代码类似于字典,因此您应该能够使用 Dictionary 实现类来指导您(即 WriteDictionary.cs 和 DeserializeDictionary.cs)

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

【讨论】:

如果我能让 MonoTouch 使用 ServiceStack 反序列化从其他系统之一生成的 JSON,那么这个特定问题实际上不会对我造成太大伤害。即使我可以解决它,我也会尝试看看我能做些什么来为拉取请求整理一些代码;在我当前项目的两端使用 ServiceStack 会很好。 当然,要让 ServiceStack 在 MonoTouch 上工作,您只需要使用 MonoTouch 构建,它可以在以下位置获得:github.com/ServiceStack/ServiceStack/tree/master/release/latest/… 这很容易。我在几分钟内启动并运行了它。如果我没有在 MonoDevelop 中重新学习键盘快捷键,那将是几秒钟的时间。

以上是关于如何使用 ServiceStack JsonSerializer 序列化 ExpandoObject?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ServiceStack 访问响应标头

如何使用 servicestack 类型的客户端?

如何修改 ServiceStack.OrmLite 生成的 SQL?

使用 JSON 时如何让 ServiceStack 用破折号格式化 Guid?

如何最好地对使用 IServiceGateway 调用其他内部服务的 ServiceStack 服务进行单元测试

Redis ServiceStack 使用事务时如何创建多个序列号