浅析JavaScriptSerializer类的序列化与反序列化
JavaScriptSerializer类由异步通信层内部使用,用于序列化和反序列化在浏览器和Web服务器之间传递的数据。说白了就是能够直接将一个C#对象传送到前台页面成为javascript对象。要添加System.Web.Extensions.dll的引用。该类位于System.Web.Script.Serialization命名空间下。
一、属性
MaxJsonLength获取或设置JavaScriptSerializer类接受的JSON字符串的最大长度。
RecursionLimit获取或设置用于约束要处理的对象级别的数目的限制。
二、方法
ConvertToType<(Of<(T>)>)将给定对象转换为指定类型。
Deserialize<(Of<(T>)>)将指定的JSON字符串转换为T类型的对象。
DeserializeObject将指定的JSON字符串转换为对象图。
RegisterConverters使用JavaScriptSerializer实例注册自定义转换器。
Serialize已重载。将对象转换为JSON字符串。
给个示例,主要就是了解了一下Serialize与Deserialize两个方法,控制器代码:
publicclassHomeController:Controller { publicActionResultIndex() { returnView(); } publicActionResultGetJson() { JavaScriptSerializerjss=newJavaScriptSerializer(); Personp=newPerson(1,"张飞",20); stringjson=jss.Serialize(p);//序列化成JSON Personp1=jss.Deserialize<Person>(json);//再反序列化为Person对象注意此方法要求目标类有无参构造函数 //returnJson(json,"text/json");//很好用,但是返回的终归是字符串,返回到前台要解析一下才能变成javascript对象。 returnJson(new{Id=p1.Id,Name=p1.Name,Age=p1.Age},"text/json");//如果这样写,返回到javascript中是不用再解析的,直接就是javascript对象 } } publicclassPerson { publicPerson() {} publicPerson(intid,stringname,intage) { this.Id=id; this.Name=name; this.Age=age; } publicintId{get;set;} publicstringName{get;set;} publicintAge{get;set;} }
前台HTML代码:
<html> <head> <title>javascriptSerializer类测试</title> <scriptsrc="/jQuery.1.8.3.js"type="text/javascript"></script> <scripttype="text/javascript"> $(function(){ $(":button").click(function(){ $.ajax({ url:"/Home/GetJson", dataType:"json", type:"post", success:function(response){ //vardata=JSON.parse(response); //$("#Id").text(data.Id); //$("#Name").text(data.Name); //$("#Age").text(data.Age); $("#Id").text(response.Id); $("#Name").text(response.Name); $("#Age").text(response.Age); } }) }) }) </script> </head> <body> <ul> <liid="Id"></li> <liid="Name"></li> <liid="Age"></li> </ul> <inputtype="button"value="确认"/> </body> </html>
试下4个基础方法与属性
classProgram { staticvoidMain(string[]args) { //方法 //RegisterConverters使用JavaScriptSerializer实例注册自定义转换器。 //属性 //RecursionLimit获取或设置用于约束要处理的对象级别的数目的限制。 JavaScriptSerializerjss=newJavaScriptSerializer(); Console.WriteLine(jss.MaxJsonLength);//默认接受最大的长度是2097152这个是接受JSON字符串的最大长度,超长会有什么后果呢?试下 jss.MaxJsonLength=1; Personp=newPerson(1,"关羽",21); //stringjson=jss.Serialize(p);//将对象序列化成Json字符串//此处报异常使用JSONJavaScriptSerializer进行序列化或反序列化时出错。字符串的长度超过了为maxJsonLength属性设置的值。 jss.MaxJsonLength=2097152; //序列化 stringjson=jss.Serialize(p); Console.WriteLine(json);//输出{"Id":1,"Name":"关羽","Age":21}`这就是Json格式了 //反序列化Deserialize Personp2=jss.Deserialize<Person>("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}"); Console.WriteLine(p2.Id+""+p2.Name+""+p2.Age);//输出1关羽21 //Deserialize的非泛型写法 Personp3=jss.Deserialize("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}",typeof(Person))asPerson;//注意这个方法返回的是object类,因此要强制转换成Person类 Console.WriteLine(p3.Id+""+p3.Name+""+p3.Age);//同样输出1关羽21 objectobj=jss.DeserializeObject("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}");//将Json字符转换为Object类型 //Personp4=objasPerson;//此行代码转为的p4为null Personp4=jss.ConvertToType<Person>(obj);//尼玛,原来这个方法是这样用的,知道DeserializeObject转换会为null所以另外写一个吗 Console.WriteLine(p4.Name);//输出关羽 //非泛型版本 Personp5=jss.ConvertToType(obj,typeof(Person))asPerson; Console.WriteLine(p5.Name);//输出关羽 Console.ReadKey(); } }
实现自定义转换器
将指定的数据类型序列化为Json。Serialize方法是个递归方法,会递归地序列化对象的属性,因此在序列化一个复杂对象(比如DataTable)时往往会出现“循环引用”的异常,这时候就需要针对复杂类型自定义一个转换器。下面是DataTable的转换器,原理是把DataTable转换成一个字典列表后再序列化:
所有自定义的转换器都要继承于JavaScriptConverter,并实现Serialize、Deserialize方法和SupportedTypes属性,其中SupportedTypes属性用于枚举此转换器支持的类型。
classProgram { staticvoidMain(string[]args) { DataTabledt=newDataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Age"); dt.Rows.Add(1,"关羽",21); dt.Rows.Add(2,"刘备",22); dt.Rows.Add(3,"张飞",20); JavaScriptSerializerjss=newJavaScriptSerializer(); //注册转换器的方法,用于复杂转换除了实现还需要注册到JavaScriptSerializer jss.RegisterConverters(newJavaScriptConverter[]{newDataTableConverter()}); stringstrJson=jss.Serialize(dt); Console.WriteLine(strJson); //输出{"Rows":[{"Id":"1","Name":"关羽","Age":"21"},{"Id":"2","Name":"刘备","Age":"22"},{"Id":"3","Name":"张飞","Age":"20"}]} Console.ReadKey(); } } ///<summary> ///DataTableJSON转换类 ///</summary> publicclassDataTableConverter:JavaScriptConverter { publicoverrideIDictionary<string,object>Serialize(objectobj,JavaScriptSerializerserializer) { DataTabledt=objasDataTable; Dictionary<string,object>result=newDictionary<string,object>(); List<Dictionary<string,object>>rows=newList<Dictionary<string,object>>(); foreach(DataRowdrindt.Rows) { Dictionary<string,object>row=newDictionary<string,object>(); foreach(DataColumndcindt.Columns) { row.Add(dc.ColumnName,dr[dc.ColumnName]); } rows.Add(row); } result["Rows"]=rows; returnresult; } publicoverrideobjectDeserialize(IDictionary<string,object>dictionary,Typetype,JavaScriptSerializerserializer) { thrownewNotImplementedException(); } ///<summary> ///获取本转换器支持的类型 ///</summary> publicoverrideIEnumerable<Type>SupportedTypes { get{returnnewType[]{typeof(DataTable)};} } }
限制序列化的层次
classProgram { staticvoidMain(string[]args) { JavaScriptSerializerjss=newJavaScriptSerializer(); Console.WriteLine(jss.RecursionLimit);//默认的序列化层次是100 Personp1=newPerson(1,"刘备",24); p1.p=newPerson(2,"关羽",23); p1.p.p=newPerson(3,"张飞",21); stringstrJson=jss.Serialize(p1); Console.WriteLine(strJson); //输出{"Id":1,"Name":"刘备","Age":24,"p":{"Id":2,"Name":"关羽","Age":23,"p":{"Id":3,"Name":"张飞","Age":21,"p":null}}} //现在将层次减少到1 jss.RecursionLimit=1; stringstrJson2=jss.Serialize(p1);//这行代码是报异常的,显示已超出RecursionLimit。这就是这个属性的作用 //最后再来说一个特性,比如如果我有某一个属性不希望它序列化,那么可以设置添加 Console.ReadKey(); } } publicclassPerson { publicPerson() {} publicPerson(intid,stringname,intage) { this.Id=id; this.Name=name; this.Age=age; } publicintId{get;set;} publicstringName{get;set;} publicintAge{get;set;} //里面嵌套一个Person publicPersonp{get;set;} }
[ScriptIgnore]禁止某属性序列化
classProgram { staticvoidMain(string[]args) { JavaScriptSerializerjss=newJavaScriptSerializer(); Personp=newPerson(1,"刘备",24); Console.WriteLine(jss.Serialize(p)); File.WriteAllText(@"D:\123.txt",jss.Serialize(p));//输出{"Id":1,"Age":24} Console.ReadKey(); } } publicclassPerson { publicPerson() {} publicPerson(intid,stringname,intage) { this.Id=id; this.Name=name; this.Age=age; } publicintId{get;set;} [ScriptIgnore] publicstringName{get;set;} publicintAge{get;set;} }
以上就是本文的全部内容,希望对大家有所帮助,谢谢对毛票票的支持!