如何使用ServiceStack JsonSerializer连载ExpandoObject? [英] How to serialize ExpandoObject using ServiceStack JsonSerializer?

查看:209
本文介绍了如何使用ServiceStack JsonSerializer连载ExpandoObject?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能得到ServiceStack JsonSerializer序列化一个ExpandoObject作为平面物体,而不是一本字典?东西大致近似这样:

  {X:xvalue,Y:\ /日期(1313966045485 )\ /} 

我想比较的JSON序列化 ExpandoObject 使用三种不同的系统:在.NET BCL的JavaScriptSerializer,Newtonsoft JSON.NET和ServiceStack的JSON发行



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

 动态测试=新ExpandoObject(); 
test.x =xvalue;
test.y = DateTime.Now;



这似乎是一个串行简单的把一个ExpandoObject为的IDictionary<字符串,对象> 。 ,两者BCL和ServiceStack开始就这样,虽然会致使相当不同的路线

 的JavaScriptSerializer的JavaScriptSerializer =新的JavaScriptSerializer(); 
Console.WriteLine(javaScriptSerializer.Serialize(试验));
// [{关键:X,值:xvalue},{关键:Y,值:\ /日期(1313966045485)\ / }]

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(试验));
// [[X,xvalue],[Y,2011年8月21日下午16时59分34秒]]

我宁愿因为它是组装的代码,就像一个典型的类将被序列化ExpandoObject序列化了。您可以添加覆盖的JavaScript序列化,为的IDictionary<的BCL系统,字符串,对象> 。这个伟大的工程,假设一个不确实有一个的IDictionary<字符串对象> 需要保持这样的(我不还)



 的JavaScriptSerializer的JavaScriptSerializer =新的JavaScriptSerializer(); 
javaScriptSerializer.RegisterConverters(新JavaScriptConverter [] {新ExpandoJsonConverter()});
Console.WriteLine(javaScriptSerializer.Serialize(试验));
// {X:xvalue,Y:\ /日期(1313966045485)\ /}

不幸的是,我还需要一种方式来获得ServiceStack的JsonSerializer以同样的方式对待一个ExpandoObject。我如何钩到ServiceStack系统,使这成为可能。



更新:虽然它不是我使用的一个选项,它看起来像ServiceStack处理匿名对象就好了。

  Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(新{X =xvalue ,Y = DateTime.Now})); 
// {X:xvalue,Y:\ /日期(1313980029620 + 0000)\ /}


解决方案

有没有ServiceStack的JsonSerializer任何可用的钩子,你可以插入改变这种行为,但我更乐意采取这种做它一拉请求;)



您将需要更改的类是:




  • JsWriter的.cs (223线) - 插入代码来检测的expando对象,并返回写入你想要的了的expando对象的委托。

  • JsReader (42号线) - 插入代码来检测的expando对象,并返回一个委托读取字符串的内容和反序列化回在Expando



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



随意使用ServiceStack论坛,如果您有任何疑问/问题这个:
https://groups.google.com/forum/#!forum/servicestack


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

解决方案

There aren't any hooks available in ServiceStack's JsonSerializer that you can plug into to change this behaviour but I'm be more than happy to take a pull request that does it ;)

The classes you will need to change are:

  • JsWriter.cs (Line 223) - insert code to detect an expando object and return a delegate that writes the expando object how you want it.
  • JsReader (Line 42) - insert code to detect an expando object and return a delegate to read the contents of a string and deserialize it back into an expando

I imagine the code for dealing with an expando object is similar to a dictionary so you should be able to use the Dictionary implementation classes to guide you (i.e. WriteDictionary.cs and DeserializeDictionary.cs)

Feel free to use the ServiceStack forum if you have any more questions/issues on this: https://groups.google.com/forum/#!forum/servicestack

这篇关于如何使用ServiceStack JsonSerializer连载ExpandoObject?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆