在传统.NET程序中使用Silverlight SDK里的JSON类库
2010-10-12 17:34 by 老赵, 3878 visits话说在Silverlight SDK中提供了一套JSON类库,叫做System.Json。这个类库功能很简单,就是使用.NET来表示JSON格式的“结构”。换句话说,就是我之前在JsonMe中所提到的JsonObject,JsonArray之类的东西,但完全不包括JSON结构和实际类型之间的转化。虽然这个类库很不好用(谁用谁知道),但至少是一个可以通用于Silverlight和MonoTouch的类库,因此我决定将JsonMe基于它进行构建。为此,我对mono中的开源实现进行了移植,使它仅仅依赖于功能最基本的.NET Framework 3.5 Client Profile,并修改了其中的一些明显的Bug。
Mono的项目源码可以从github里获得,或者您直接下载mono 2.8的源码tar包,不过现在我们只需要其中的System.Json。System.Json,只有五个文件,不过它依赖了mono的System.ServiceModel.Web.dll里定义的JavaScriptReader和JavaScriptObjectDeserializer类,因此我也将这两个内部类一并移植到System.Json项目中。因此,最终项目的组织结构如下:
从上图中可以看出,如今的System.Json项目只依赖了极少的系统类库,事实上它可以在.NET Framework 3.5 Client Profile下运行,这样无论是Silverlight还是普通的客户端都可以使用它的功能,这是依赖System.Web.Extensions.dll的时候所无法做到的。同样,JsonMe也已经进行了相应的改写,现在它已经能够用于Silverlight,MonoTouch,甚至未来的MonoDroid中。不过基于System.Json之后JsonMe反而因此变得复杂了,这是因为System.Json实在不是一个好用的类库。
mono的System.Json还存在一个bug:JsonObject的Add方法不允许value为null,这是个十足的问题,使得类库无法支持null值。我使用.NET Reflector检查了Silverlight中的实现,它并没有这样的约束,这才符合我的预期。将这个约束去除以后,序列化成JSON字符串的逻辑便会引发NullReferenceException,因此我也修改了对应的序列化逻辑。此外,如果您用DateTime创建一个JsonPrimitive类型,序列化时也会出现问题。我还不太清楚Silverlight SDK中是如何处理这个情况的,再我看来在JSON中放置DateTime也是一个很奇怪的行为,还是先转化为字符串吧。杯具的是,MonoTouch SDK中也有这些bug,不幸中的万幸,只要在MonoTouch重新编译我移植的代码就行了。
如果您对此感兴趣,也不妨获取这些代码捣鼓捣鼓。
正准备申请个github账号呢