在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、JSON简介 在正式讨论JSON格式之前,首先让我们简要回忆一下XML。XML是“可扩展的标记语言”的简称,它提供了定义Web中一系列数据传输协议的方式,是文本型的,被人们誉为“完全开发Internet和Web潜力的理想方式”。 那么,为什么ASP.NET AJAX中还要引入JSON呢?还是让我们先来观察一下例子吧。比如当前Web页面将从后台载入一些通讯录的信息,这些信息如果写成XML,可能是如下形式: <contact> 而写成JSON形式,则会是: [ 相比之下,后面JSON表达方式明显更为简洁。其实,我们最关心的并不只是表达上的简单性,最重要的是如何简化DOM的解析。因为不同的浏览器中XML/SOAP解释器的实现是有所不同的,所以,解释相同的XML和SOAP格式的数据未必会一定得到一致的结果。为此,ASP.NET AJAX中特地引入了更为轻量级的JSON格式,并创建了一致的JSON解析器,再加上JavaScript本身就支持以JSON方式创建对象,所以,这一切都显然十分流畅自然和水到渠成。 JSON,即JavaScript对象标志,如今已经成为JavaScript内置支持的数据格式,它实现了比以前的XML和SOAP更为有效的网络数据传送方式。简言之,JSON是一种基本的把对象序列化成轻量级字符串的方式,而字符串数据可以轻松地通过网络进行数据传输而且毫不失真。我们不妨再来考虑下面简单的C#类: public class User 现在,假设定义了上面对象的如下实例:
User usr = new User(); 当把上面数据序列化成JSON格式的文本时,最终会得到如下所示的形式: { FirstName : "John" 借助于JavaScript内置支持的方法eval()或者ASP.NET AJAX提供的Sys.Serialization.JavaScriptSerializer类,我们可以在JavaScript代码中实现JSON文本串的反序列化(即再还原成最初的对象形式)。 在本文中,我们将专注于讨论使用ASP.NET AJAX提供的特有类来实现把一个JavaScript对象序列化为文本串,然后发送到服务器端,以及如何使用服务器端类JavaScriptSerializer把JSON文本串反序列化成原始的对象数据。
二、实现序列/反序列化的关键—JavaScriptSerializer
实现序列化及反序列化的对象是JavaScriptSerializer。下面,我们来具体地看一下这个对象的成员定义情况:
public class JavaScriptSerializer //方法 //属性 首先需要注意的是,如果嵌套的对象数目大于RecursionLimit属性中所定义的值100的话,序列化过程将会失败。显然,如果序列化后的字符串的长度超出MaxJsonLength属性所定义的值0x200000(即十进制的2,097,152)的话,序列化过程也会失败。 此外,通过上面代码也可以看出,对象将被序列化为一个StringBuilder对象,最后返回相应的字符串数据。其实,主要的工作是在私有方法SerializeValue()中完成的。在我们讨论这个方法之前,首先注意到,JavaScriptSerializer对象使用了JavaScriptTypeResolver对象。这个JavaScript类型解析器负责实现在字符串类型与其他类型之间的相互转换;当序列化定制对象时这一功能是非常重要的。还应注意的是,__type属性将被包含于JSON序列化文本中,以便标识对象的类型。之后,客户端会把JSON文本反序列化为原始的对象形式。 JavaScriptTypeResolver对象包括两个public类型的方法,一个负责把原始类型解析为字符串类型,另一个则负责把字符串解析为原始类型。这个类的原型定义如下所示: public abstract class JavaScriptTypeResolver
显然,上面这个JavaScriptTypeResolver类是一个抽象基类;因此,必须通过其他对象进一步派生使用,从而最终实现在原始类型与字符串之间的相应解析。现在,我们可以使用的对象是SimpleTypeResolver,而且它也正好实现了上面所要求实现的方法—使用System.Type对象实现字符串描述形式与原始Type对象之间的相互解析。请看下面的例子: public override Type ResolveType(string id) 最后,JavaScriptSerializer对象还有可能使用JavaScriptConverter对象,因为内置的序列化过程无法实现对于所有可用数据类型的序列化。在这种情况下,可以从抽象基类JavaScriptConverter对象派生一个子类,由它来实现特定类型数据的序列/反序列化。可以使用JavaScriptSerializer对象的RegisterConverters()方法注册一个转换器对象。此方法把所有的转换器对象存储在一个Dictionary对象中;针对多种不同的数据类型的转换器经注册后都会存储在此字典对象中。概括来看,这个Dictionary对象被定义如表格1所示的一些数据类型。 表1—可序列化的数据类型汇总
三、序列/反序列化举例
现在,让我们通过一个例子来具体分析一下序列化过程。首先,请考虑下面定义的Customer对象: public class Customer
JavaScriptSerializer jsSerializer = new 根据前面的分析,JavaScriptSerializer对象已经使用SimpleTypeResolver初始化完毕(其中,SimpleTypeResolver负责把要序列化的对象转换成一个字符串形式)。下面,我们来看一下序列化之后的JSON文本: {"__type":"Customer, App_Web_plrzlwbj, 注意,其中的PhoneNumbers属性属于定制类型—Phone。因此,当被序列化时,PhoneNumbers属性的值本身就是一个JSON对象,它正是Phone对象的序列化之后的形式。再次强调的是,这里添加了类型标记,以备反序列化时使用,从而确保创建相应类型的原始对象。 接下来,再让我们来看一下反序列化的过程。 反序列化过程是借助于JavaScriptObjectDeserializer对象实现的。当创建一个对象的实例时,相应的JSON文本串将会以参数方式传递到这个类的构造器中。当对象实例创建结束,我们就可以调用DeserializeInternal()方法。这个方法具体负责解析JSON序列化字符串并创建相应的原始类型的对象。 上面分析了反序列化的内部实现。但是,作为使用JavaScriptSerializer类的程序员,要实现一个JSON字符串的反序列化,我们只需简单地调用JavaScriptSerializer对象的Deserialize()方法。这个方法的返回值正相应于原始对象的一个实例,而且相应的属性也被进行了正确的赋值。我们不妨来考虑下面的代码: Customer cust = jsSerializer.Deserialize(serializedText); 在此,不再给出变量cust的内容展现,有兴趣的读者可以自动跟踪分析。
四、关于客户端JavaScriptSerializer对象
ASP.NET AJAX客户端框架中的Microsoft Ajax Library也提供了一个Sys.Serialization.JavaScriptSerializer对象,从而方便在基于非ASP.NET平台上的ASP.NET AJAX编程中的JSON数据的编码与解码。这个JavaScriptSerializer对象暴露了两个方法:serialize和deserialize。 其中,serialize方法接受一个JavaScript对象形式的参数,此函数返回一个描述JSON数据的字符串,例如: var man = {firstName: 'John', lastName: 'Mike'}; var s1 = Sys.Serialization.JavaScriptSerializer; var json = s1.serialize(man); 在此,变量json中存储了一个字符串,这个串中相应于变量man中存储的对象的JSON描述形式。 而deserialize方法执行与serialize方法相反的任 务。它接受一个JSON字符串形式的参数,返回的是相应的JavaScript对象,例如:
var man = serializer.deserialize(json); 最后需要注意的一点是,当你使用JSON分析器时,你需要小心日期数据的处理方式,这是因为JavaScript并不直接支持日期格式的数据。更多的有关日期格式的数据的JSON操作请参考官方网站提供的示例,在此不再赘述。
四、关于客户端JavaScriptSerializer对象
ASP.NET AJAX客户端框架中的Microsoft Ajax Library也提供了一个Sys.Serialization.JavaScriptSerializer对象,从而方便在基于非ASP.NET平台上的ASP.NET AJAX编程中的JSON数据的编码与解码。这个JavaScriptSerializer对象暴露了两个方法:serialize和deserialize。 其中,serialize方法接受一个JavaScript对象形式的参数,此函数返回一个描述JSON数据的字符串,例如: var man = {firstName: 'John', lastName: 'Mike'}; var s1 = Sys.Serialization.JavaScriptSerializer; var json = s1.serialize(man); 在此,变量json中存储了一个字符串,这个串中相应于变量man中存储的对象的JSON描述形式。 而deserialize方法执行与serialize方法相反的任务。它接受一个JSON字符串形式的参数,返回的是相应的JavaScript对象,例如: var man = serializer.deserialize(json); 最后需要注意的一点是,当你使用JSON分析器时,你需要小心日期数据的处理方式,这是因为JavaScript并不直接支持日期格式的数据。更多的有关日期格式的数据的JSON操作请参考官方网站提供的示例,在此不再赘述。 |
请发表评论