淺析JavaScriptSerializer類的序列化與反序列化
JavaScriptSerializer 類由異步通信層內(nèi)部使用,用于序列化和反序列化在瀏覽器和 Web 服務(wù)器之間傳遞的數(shù)據(jù)。說白了就是能夠直接將一個C#對象傳送到前臺頁面成為javascript對象。要添加System.Web.Extensions.dll的引用。該類位于System.Web.Script.Serialization命名空間下。
一、屬性
MaxJsonLength 獲取或設(shè)置 JavaScriptSerializer 類接受的 JSON 字符串的最大長度。
RecursionLimit 獲取或設(shè)置用于約束要處理的對象級別的數(shù)目的限制。
二、方法
ConvertToType<(Of <(T>)>) 將給定對象轉(zhuǎn)換為指定類型。
Deserialize<(Of <(T>)>) 將指定的 JSON 字符串轉(zhuǎn)換為 T 類型的對象。
DeserializeObject 將指定的 JSON 字符串轉(zhuǎn)換為對象圖。
RegisterConverters 使用 JavaScriptSerializer 實(shí)例注冊自定義轉(zhuǎn)換器。
Serialize 已重載。 將對象轉(zhuǎn)換為 JSON 字符串。
給個示例,主要就是了解了一下Serialize與Deserialize兩個方法,控制器代碼:
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對象 注意此方法要求目標(biāo)類有無參構(gòu)造函數(shù)
//return Json(json, "text/json"); //很好用,但是返回的終歸是字符串,返回到前臺要解析一下才能變成javascript對象。
return Json(new { Id = p1.Id, Name = p1.Name, Age = p1.Age }, "text/json");//如果這樣寫,返回到j(luò)avascript中是不用再解析的,直接就是javascript對象
}
}
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; }
}
前臺HTML代碼:
<html>
<head>
<title>javascriptSerializer類測試</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個基礎(chǔ)方法與屬性
class Program
{
static void Main(string[] args)
{
// 方法
// RegisterConverters 使用 JavaScriptSerializer 實(shí)例注冊自定義轉(zhuǎn)換器。
//屬性
// RecursionLimit 獲取或設(shè)置用于約束要處理的對象級別的數(shù)目的限制。
JavaScriptSerializer jss = new JavaScriptSerializer();
Console.WriteLine(jss.MaxJsonLength); //默認(rèn)接受最大的長度是 2097152 這個是接受JSON字符串的最大長度,超長會有什么后果呢?試下
jss.MaxJsonLength = 1;
Person p = new Person(1,"關(guān)羽",21);
//string json = jss.Serialize(p); //將對象序列化成Json字符串 //此處報異常使用 JSON JavaScriptSerializer 進(jìn)行序列化或反序列化時出錯。字符串的長度超過了為 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; //注意這個方法返回的是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); //原來這個方法是這樣用的,知道DeserializeObject轉(zhuǎn)換會為null所以另外寫一個嗎
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方法是個遞歸方法,會遞歸地序列化對象的屬性,因此在序列化一個復(fù)雜對象(比如DataTable)時往往會出現(xiàn)“循環(huán)引用”的異常,這時候就需要針對復(fù)雜類型自定義一個轉(zhuǎn)換器。下面是DataTable的轉(zhuǎn)換器,原理是把DataTable轉(zhuǎn)換成一個字典列表后再序列化:
所有自定義的轉(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();
//注冊轉(zhuǎn)換器的方法,用于復(fù)雜轉(zhuǎn)換 除了實(shí)現(xiàn)還需要注冊到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);//這行代碼是報異常的,顯示已超出 RecursionLimit。 這就是這個屬性的作用
//最后再來說一個特性,比如如果我有某一個屬性不希望它序列化,那么可以設(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; }
//里面嵌套一個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; }
}
以上就是本文的全部內(nèi)容,希望對大家有所幫助,謝謝對腳本之家的支持!
- django restframework serializer 增加自定義字段操作
- django rest framework serializers序列化實(shí)例
- django rest framework serializer返回時間自動格式化方法
- Django Serializer HiddenField隱藏字段實(shí)例
- django序列化serializers過程解析
- django自帶serializers序列化返回指定字段的方法
- django Serializer序列化使用方法詳解
- 詳解django的serializer序列化model幾種方法
- C#使用JavaScriptSerializer序列化時的時間類型處理
- C# xmlSerializer簡單用法示例
- C#中JavaScriptSerializer幫助類用法實(shí)例
- Python基于Serializer實(shí)現(xiàn)字段驗證及序列化
相關(guān)文章
javascript實(shí)現(xiàn)狀態(tài)欄中文字動態(tài)顯示的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)狀態(tài)欄中文字動態(tài)顯示的方法,涉及JavaScript基于時間函數(shù)動態(tài)操作頁面元素屬性的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
JS removeAttribute()方法實(shí)現(xiàn)刪除元素的某個屬性
這篇文章主要介紹了JS removeAttribute()方法實(shí)現(xiàn)刪除元素的某個屬性,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
javaScript中with函數(shù)用法實(shí)例分析
這篇文章主要介紹了javaScript中with函數(shù)用法,實(shí)例分析了javascript中with的功能、定義及相關(guān)使用技巧,需要的朋友可以參考下2015-06-06
漫談JS引擎的運(yùn)行機(jī)制 你應(yīng)該知道什么
javascript 從定義到執(zhí)行,你應(yīng)該知道的那些事,本文為大家一一列舉,希望對大家的學(xué)習(xí)有所幫助2016-06-06
使用JS簡單實(shí)現(xiàn)apply、call和bind方法的實(shí)例代碼
在JavaScript中,call、apply和bind是Function對象自帶的三個方法,這三個方法的主要作用是改變函數(shù)中的this指向,下面這篇文章主要給大家介紹了關(guān)于如何使用JS簡單實(shí)現(xiàn)apply、call和bind方法的相關(guān)資料,需要的朋友可以參考下2022-02-02

