淺析JavaScriptSerializer類的序列化與反序列化
JavaScriptSerializer 類由異步通信層內(nèi)部使用,用于序列化和反序列化在瀏覽器和 Web 服務(wù)器之間傳遞的數(shù)據(jù)。說白了就是能夠直接將一個(gè)C#對(duì)象傳送到前臺(tái)頁面成為javascript對(duì)象。要添加System.Web.Extensions.dll的引用。該類位于System.Web.Script.Serialization命名空間下。
一、屬性
MaxJsonLength 獲取或設(shè)置 JavaScriptSerializer 類接受的 JSON 字符串的最大長(zhǎng)度。
RecursionLimit 獲取或設(shè)置用于約束要處理的對(duì)象級(jí)別的數(shù)目的限制。
二、方法
ConvertToType<(Of <(T>)>) 將給定對(duì)象轉(zhuǎn)換為指定類型。
Deserialize<(Of <(T>)>) 將指定的 JSON 字符串轉(zhuǎn)換為 T 類型的對(duì)象。
DeserializeObject 將指定的 JSON 字符串轉(zhuǎn)換為對(duì)象圖。
RegisterConverters 使用 JavaScriptSerializer 實(shí)例注冊(cè)自定義轉(zhuǎn)換器。
Serialize 已重載。 將對(duì)象轉(zhuǎn)換為 JSON 字符串。
給個(gè)示例,主要就是了解了一下Serialize與Deserialize兩個(gè)方法,控制器代碼:
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult GetJson() { JavaScriptSerializer jss = new JavaScriptSerializer(); Person p = new Person(1, "張飛", 20); string json = jss.Serialize(p); //序列化成JSON Person p1 = jss.Deserialize<Person>(json); //再反序列化為Person對(duì)象 注意此方法要求目標(biāo)類有無參構(gòu)造函數(shù) //return Json(json, "text/json"); //很好用,但是返回的終歸是字符串,返回到前臺(tái)要解析一下才能變成javascript對(duì)象。 return Json(new { Id = p1.Id, Name = p1.Name, Age = p1.Age }, "text/json");//如果這樣寫,返回到j(luò)avascript中是不用再解析的,直接就是javascript對(duì)象 } } public class Person { public Person() { } public Person(int id, string name, int age) { this.Id = id; this.Name = name; this.Age = age; } public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
前臺(tái)HTML代碼:
<html> <head> <title>javascriptSerializer類測(cè)試</title> <script src="/jQuery.1.8.3.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $(":button").click(function () { $.ajax({ url: "/Home/GetJson", dataType: "json", type: "post", success: function (response) { // var data = 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> <li id="Id"></li> <li id="Name"></li> <li id="Age"></li> </ul> <input type="button" value="確認(rèn)" /> </body> </html>
試下4個(gè)基礎(chǔ)方法與屬性
class Program { static void Main(string[] args) { // 方法 // RegisterConverters 使用 JavaScriptSerializer 實(shí)例注冊(cè)自定義轉(zhuǎn)換器。 //屬性 // RecursionLimit 獲取或設(shè)置用于約束要處理的對(duì)象級(jí)別的數(shù)目的限制。 JavaScriptSerializer jss = new JavaScriptSerializer(); Console.WriteLine(jss.MaxJsonLength); //默認(rèn)接受最大的長(zhǎng)度是 2097152 這個(gè)是接受JSON字符串的最大長(zhǎng)度,超長(zhǎng)會(huì)有什么后果呢?試下 jss.MaxJsonLength = 1; Person p = new Person(1,"關(guān)羽",21); //string json = jss.Serialize(p); //將對(duì)象序列化成Json字符串 //此處報(bào)異常使用 JSON JavaScriptSerializer 進(jìn)行序列化或反序列化時(shí)出錯(cuò)。字符串的長(zhǎng)度超過了為 maxJsonLength 屬性設(shè)置的值。 jss.MaxJsonLength = 2097152; //序列化 string json = jss.Serialize(p); Console.WriteLine(json); //輸出 {"Id":1,"Name":"關(guān)羽","Age":21}`這就是Json格式了 //反序列化Deserialize Person p2 = jss.Deserialize<Person>("{\"Id\":1,\"Name\":\"關(guān)羽\",\"Age\":21}"); Console.WriteLine(p2.Id + " " + p2.Name + " " + p2.Age); //輸出 1 關(guān)羽 21 //Deserialize的非泛型寫法 Person p3 = jss.Deserialize("{\"Id\":1,\"Name\":\"關(guān)羽\",\"Age\":21}",typeof(Person)) as Person; //注意這個(gè)方法返回的是object類,因此要強(qiáng)制轉(zhuǎn)換成Person類 Console.WriteLine(p3.Id + " " + p3.Name + " " + p3.Age); //同樣輸出 1 關(guān)羽 21 object obj = jss.DeserializeObject("{\"Id\":1,\"Name\":\"關(guān)羽\",\"Age\":21}"); //將Json字符轉(zhuǎn)換為Object類型 //Person p4 = obj as Person; //此行代碼轉(zhuǎn)為的p4為null Person p4 = jss.ConvertToType<Person>(obj); //尼瑪,原來這個(gè)方法是這樣用的,知道DeserializeObject轉(zhuǎn)換會(huì)為null所以另外寫一個(gè)嗎 Console.WriteLine(p4.Name); //輸出關(guān)羽 //非泛型版本 Person p5 = jss.ConvertToType(obj,typeof(Person)) as Person; Console.WriteLine(p5.Name); //輸出關(guān)羽 Console.ReadKey(); } }
實(shí)現(xiàn)自定義轉(zhuǎn)換器
將指定的數(shù)據(jù)類型序列化為Json。Serialize方法是個(gè)遞歸方法,會(huì)遞歸地序列化對(duì)象的屬性,因此在序列化一個(gè)復(fù)雜對(duì)象(比如DataTable)時(shí)往往會(huì)出現(xiàn)“循環(huán)引用”的異常,這時(shí)候就需要針對(duì)復(fù)雜類型自定義一個(gè)轉(zhuǎn)換器。下面是DataTable的轉(zhuǎn)換器,原理是把DataTable轉(zhuǎn)換成一個(gè)字典列表后再序列化:
所有自定義的轉(zhuǎn)換器都要繼承于JavaScriptConverter,并實(shí)現(xiàn)Serialize、Deserialize方法和SupportedTypes屬性,其中SupportedTypes屬性用于枚舉此轉(zhuǎn)換器支持的類型。
class Program { static void Main(string[] args) { DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Age"); dt.Rows.Add(1, "關(guān)羽", 21); dt.Rows.Add(2, "劉備", 22); dt.Rows.Add(3, "張飛", 20); JavaScriptSerializer jss = new JavaScriptSerializer(); //注冊(cè)轉(zhuǎn)換器的方法,用于復(fù)雜轉(zhuǎn)換 除了實(shí)現(xiàn)還需要注冊(cè)到JavaScriptSerializer jss.RegisterConverters(new JavaScriptConverter[] { new DataTableConverter() }); string strJson = jss.Serialize(dt); Console.WriteLine(strJson); //輸出 {"Rows":[{"Id":"1","Name":"關(guān)羽","Age":"21"},{"Id":"2","Name":"劉備","Age":"22"},{"Id":"3","Name":"張飛","Age":"20"}]} Console.ReadKey(); } } /// <summary> /// DataTable JSON轉(zhuǎn)換類 /// </summary> public class DataTableConverter : JavaScriptConverter { public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { DataTable dt = obj as DataTable; Dictionary<string, object> result = new Dictionary<string, object>(); List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>(); foreach (DataRow dr in dt.Rows) { Dictionary<string, object> row = new Dictionary<string, object>(); foreach (DataColumn dc in dt.Columns) { row.Add(dc.ColumnName, dr[dc.ColumnName]); } rows.Add(row); } result["Rows"] = rows; return result; } public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { throw new NotImplementedException(); } /// <summary> /// 獲取本轉(zhuǎn)換器支持的類型 /// </summary> public override IEnumerable<Type> SupportedTypes { get { return new Type[] { typeof(DataTable) }; } } }
限制序列化的層次
class Program { static void Main(string[] args) { JavaScriptSerializer jss = new JavaScriptSerializer(); Console.WriteLine(jss.RecursionLimit); //默認(rèn)的序列化層次是100 Person p1 = new Person(1, "劉備", 24); p1.p = new Person(2, "關(guān)羽", 23); p1.p.p = new Person(3, "張飛", 21); string strJson = jss.Serialize(p1); Console.WriteLine(strJson); //輸出 {"Id":1,"Name":"劉備","Age":24,"p":{"Id":2,"Name":"關(guān)羽","Age":23,"p":{"Id":3,"Name":"張飛","Age":21,"p":null}}} //現(xiàn)在將層次減少到1 jss.RecursionLimit = 1; string strJson2 = jss.Serialize(p1);//這行代碼是報(bào)異常的,顯示已超出 RecursionLimit。 這就是這個(gè)屬性的作用 //最后再來說一個(gè)特性,比如如果我有某一個(gè)屬性不希望它序列化,那么可以設(shè)置添加 Console.ReadKey(); } } public class Person { public Person() { } public Person(int id, string name, int age) { this.Id = id; this.Name = name; this.Age = age; } public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } //里面嵌套一個(gè)Person public Person p { get; set; } }
[ScriptIgnore]禁止某屬性序列化
class Program { static void Main(string[] args) { JavaScriptSerializer jss = new JavaScriptSerializer(); Person p = new Person(1,"劉備",24); Console.WriteLine(jss.Serialize(p)); File.WriteAllText(@"D:\123.txt", jss.Serialize(p)); //輸出 {"Id":1,"Age":24} Console.ReadKey(); } } public class Person { public Person() { } public Person(int id, string name, int age) { this.Id = id; this.Name = name; this.Age = age; } public int Id { get; set; } [ScriptIgnore] public string Name { get; set; } public int Age { get; set; } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家有所幫助,謝謝對(duì)腳本之家的支持!
- django restframework serializer 增加自定義字段操作
- django rest framework serializers序列化實(shí)例
- django rest framework serializer返回時(shí)間自動(dòng)格式化方法
- Django Serializer HiddenField隱藏字段實(shí)例
- django序列化serializers過程解析
- django自帶serializers序列化返回指定字段的方法
- django Serializer序列化使用方法詳解
- 詳解django的serializer序列化model幾種方法
- C#使用JavaScriptSerializer序列化時(shí)的時(shí)間類型處理
- C# xmlSerializer簡(jiǎn)單用法示例
- C#中JavaScriptSerializer幫助類用法實(shí)例
- Python基于Serializer實(shí)現(xiàn)字段驗(yàn)證及序列化
相關(guān)文章
需靈活掌握的Bootstrap預(yù)定義排版類 你精通嗎?
Bootstrap預(yù)定義排版類,做web前端開發(fā)的你精通嗎?bootstrap前端框架到底為我們預(yù)定義了那些排版的類呢?感興趣的小伙伴們可以參考一下2016-06-06JS實(shí)現(xiàn)可以用鍵盤方向鍵控制的動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)可以用鍵盤方向鍵控制的動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12每天一篇javascript學(xué)習(xí)小結(jié)(RegExp對(duì)象)
這篇文章主要介紹了javascript中的RegExp對(duì)象知識(shí)點(diǎn),對(duì)RegExp對(duì)象的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下2015-11-11JS實(shí)現(xiàn)可針對(duì)算術(shù)表達(dá)式求值的計(jì)算器功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)可針對(duì)算術(shù)表達(dá)式求值的計(jì)算器功能,可實(shí)現(xiàn)基本的數(shù)字四則運(yùn)算功能,涉及javascript基本數(shù)值運(yùn)算與流程控制、判斷等操作技巧,需要的朋友可以參考下2018-09-09js+SVG實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了js+SVG實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07JavaScript中兩個(gè)感嘆號(hào)的作用說明
用兩個(gè)感嘆號(hào)的作用就在于,如果明確設(shè)置了o中flag的值(非null/undefined/0""/等值),自然test就會(huì)取跟o.flag一樣的值;如果沒有設(shè)置,test就會(huì)默認(rèn)為false,而不是null或undefined2011-12-12