首頁 web前端 js教程 淺析JavaScriptSerializer類別的序列化與反序列化

淺析JavaScriptSerializer類別的序列化與反序列化

Dec 05, 2016 pm 05:17 PM
javascript

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两个方法,控制器代码:

public class HomeController : Controller
 {
  public ActionResult Index()
  {
   return View();
  }
 
  public ActionResult GetJson()
  {
   JavaScriptSerializer jss = new JavaScriptSerializer();
   Person p = new Person(1, &quot;张飞&quot;, 20);
   string json = jss.Serialize(p); //序列化成JSON
   Person p1 = jss.Deserialize&lt;Person&gt;(json); //再反序列化为Person对象 注意此方法要求目标类有无参构造函数
   //return Json(json, &quot;text/json&quot;);  //很好用,但是返回的终归是字符串,返回到前台要解析一下才能变成javascript对象。
   return Json(new { Id = p1.Id, Name = p1.Name, Age = p1.Age }, &quot;text/json&quot;);//如果这样写,返回到javascript中是不用再解析的,直接就是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代码:

&lt;html&gt;
&lt;head&gt;
 &lt;title&gt;javascriptSerializer类测试&lt;/title&gt;
 &lt;script src=&quot;/jQuery.1.8.3.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
 &lt;script type=&quot;text/javascript&quot;&gt;
  $(function () {
   $(&quot;:button&quot;).click(function () {
    $.ajax({
     url: &quot;/Home/GetJson&quot;,
     dataType: &quot;json&quot;,
     type: &quot;post&quot;,
     success: function (response) {
//      var data = JSON.parse(response);
//      $(&quot;#Id&quot;).text(data.Id);
//      $(&quot;#Name&quot;).text(data.Name);
//      $(&quot;#Age&quot;).text(data.Age);
 
      $(&quot;#Id&quot;).text(response.Id);
      $(&quot;#Name&quot;).text(response.Name);
      $(&quot;#Age&quot;).text(response.Age);
     }
    })
   })
  })
 &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
 &lt;ul&gt;
  &lt;li id=&quot;Id&quot;&gt;&lt;/li&gt;
  &lt;li id=&quot;Name&quot;&gt;&lt;/li&gt;
  &lt;li id=&quot;Age&quot;&gt;&lt;/li&gt;
 &lt;/ul&gt;
 &lt;input type=&quot;button&quot; value=&quot;确认&quot; /&gt;
&lt;/body&gt;
&lt;/html&gt;
登入後複製

试下4个基础方法与属性

class Program
 {
  static void Main(string[] args)
  {
   // 方法 
   // RegisterConverters 使用 JavaScriptSerializer 实例注册自定义转换器。 
   //属性
   // RecursionLimit 获取或设置用于约束要处理的对象级别的数目的限制。 
 
   JavaScriptSerializer jss = new JavaScriptSerializer();
   Console.WriteLine(jss.MaxJsonLength); //默认接受最大的长度是 2097152 这个是接受JSON字符串的最大长度,超长会有什么后果呢?试下
   jss.MaxJsonLength = 1;
 
   Person p = new Person(1,&quot;关羽&quot;,21);
   //string json = jss.Serialize(p);  //将对象序列化成Json字符串 //此处报异常使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值。
 
   jss.MaxJsonLength = 2097152;
    
   //序列化
   string json = jss.Serialize(p); 
   Console.WriteLine(json); //输出 {&quot;Id&quot;:1,&quot;Name&quot;:&quot;关羽&quot;,&quot;Age&quot;:21}`这就是Json格式了
 
   //反序列化Deserialize
   Person p2 = jss.Deserialize&lt;Person&gt;(&quot;{\&quot;Id\&quot;:1,\&quot;Name\&quot;:\&quot;关羽\&quot;,\&quot;Age\&quot;:21}&quot;);
   Console.WriteLine(p2.Id + &quot; &quot; + p2.Name + &quot; &quot; + p2.Age); //输出 1 关羽 21
   //Deserialize的非泛型写法
   Person p3 = jss.Deserialize(&quot;{\&quot;Id\&quot;:1,\&quot;Name\&quot;:\&quot;关羽\&quot;,\&quot;Age\&quot;:21}&quot;,typeof(Person)) as Person; //注意这个方法返回的是object类,因此要强制转换成Person类
   Console.WriteLine(p3.Id + &quot; &quot; + p3.Name + &quot; &quot; + p3.Age); //同样输出 1 关羽 21
 
   object obj = jss.DeserializeObject(&quot;{\&quot;Id\&quot;:1,\&quot;Name\&quot;:\&quot;关羽\&quot;,\&quot;Age\&quot;:21}&quot;); //将Json字符转换为Object类型
   //Person p4 = obj as Person; //此行代码转为的p4为null
   Person p4 = jss.ConvertToType&lt;Person&gt;(obj);  //尼玛,原来这个方法是这样用的,知道DeserializeObject转换会为null所以另外写一个吗
   Console.WriteLine(p4.Name);  //输出关羽
   //非泛型版本
   Person p5 = jss.ConvertToType(obj,typeof(Person)) as Person;
   Console.WriteLine(p5.Name);  //输出关羽
 
   Console.ReadKey();
  }
 }
登入後複製

实现自定义转换器

  将指定的数据类型序列化为Json。Serialize方法是个递归方法,会递归地序列化对象的属性,因此在序列化一个复杂对象(比如DataTable)时往往会出现“循环引用”的异常,这时候就需要针对复杂类型自定义一个转换器。下面是DataTable的转换器,原理是把DataTable转换成一个字典列表后再序列化:

所有自定义的转换器都要继承于JavaScriptConverter,并实现Serialize、Deserialize方法和SupportedTypes属性,其中SupportedTypes属性用于枚举此转换器支持的类型。

class Program
 {
  static void Main(string[] args)
  {
   DataTable dt = new DataTable();
   dt.Columns.Add(&quot;Id&quot;);
   dt.Columns.Add(&quot;Name&quot;);
   dt.Columns.Add(&quot;Age&quot;);
   dt.Rows.Add(1, &quot;关羽&quot;, 21);
   dt.Rows.Add(2, &quot;刘备&quot;, 22);
   dt.Rows.Add(3, &quot;张飞&quot;, 20);
 
   JavaScriptSerializer jss = new JavaScriptSerializer();
   //注册转换器的方法,用于复杂转换  除了实现还需要注册到JavaScriptSerializer
   jss.RegisterConverters(new JavaScriptConverter[] { new DataTableConverter() });
 
   string strJson = jss.Serialize(dt);
   Console.WriteLine(strJson);
   //输出 {&quot;Rows&quot;:[{&quot;Id&quot;:&quot;1&quot;,&quot;Name&quot;:&quot;关羽&quot;,&quot;Age&quot;:&quot;21&quot;},{&quot;Id&quot;:&quot;2&quot;,&quot;Name&quot;:&quot;刘备&quot;,&quot;Age&quot;:&quot;22&quot;},{&quot;Id&quot;:&quot;3&quot;,&quot;Name&quot;:&quot;张飞&quot;,&quot;Age&quot;:&quot;20&quot;}]}
 
   Console.ReadKey();
  }
 }
 
 /// &lt;summary&gt;
 /// DataTable JSON转换类
 /// &lt;/summary&gt;
 public class DataTableConverter : JavaScriptConverter
 {
  public override IDictionary&lt;string, object&gt; Serialize(object obj, JavaScriptSerializer serializer)
  {
   DataTable dt = obj as DataTable;
   Dictionary&lt;string, object&gt; result = new Dictionary&lt;string, object&gt;();
 
   List&lt;Dictionary&lt;string, object&gt;&gt; rows = new List&lt;Dictionary&lt;string, object&gt;&gt;();
 
   foreach (DataRow dr in dt.Rows)
   {
    Dictionary&lt;string, object&gt; row = new Dictionary&lt;string, object&gt;();
    foreach (DataColumn dc in dt.Columns)
    {
     row.Add(dc.ColumnName, dr[dc.ColumnName]);
    }
    rows.Add(row);
   }
 
   result[&quot;Rows&quot;] = rows;
 
   return result;
  }
 
  public override object Deserialize(IDictionary&lt;string, object&gt; dictionary, Type type, JavaScriptSerializer serializer)
  {
   throw new NotImplementedException();
  }
 
  /// &lt;summary&gt;
  /// 获取本转换器支持的类型
  /// &lt;/summary&gt;
  public override IEnumerable&lt;Type&gt; SupportedTypes
  {
   get { return new Type[] { typeof(DataTable) }; }
  }
 }
登入後複製

限制序列化的层次

class Program
{
 static void Main(string[] args)
 {
  JavaScriptSerializer jss = new JavaScriptSerializer();
  Console.WriteLine(jss.RecursionLimit); //默认的序列化层次是100
 
  Person p1 = new Person(1, &quot;刘备&quot;, 24);
  p1.p = new Person(2, &quot;关羽&quot;, 23);
  p1.p.p = new Person(3, &quot;张飞&quot;, 21);
 
  string strJson = jss.Serialize(p1);
  Console.WriteLine(strJson);
  //输出 {&quot;Id&quot;:1,&quot;Name&quot;:&quot;刘备&quot;,&quot;Age&quot;:24,&quot;p&quot;:{&quot;Id&quot;:2,&quot;Name&quot;:&quot;关羽&quot;,&quot;Age&quot;:23,&quot;p&quot;:{&quot;Id&quot;:3,&quot;Name&quot;:&quot;张飞&quot;,&quot;Age&quot;:21,&quot;p&quot;:null}}}
 
  //现在将层次减少到1
  jss.RecursionLimit = 1;
  string strJson2 = jss.Serialize(p1);//这行代码是报异常的,显示已超出 RecursionLimit。 这就是这个属性的作用
   
  //最后再来说一个特性,比如如果我有某一个属性不希望它序列化,那么可以设置添加
   
  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,&quot;刘备&quot;,24);
   Console.WriteLine(jss.Serialize(p));
   File.WriteAllText(@&quot;D:\123.txt&quot;, jss.Serialize(p)); //输出 {&quot;Id&quot;:1,&quot;Age&quot;: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; }
 }
登入後複製


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章標籤

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

簡易JavaScript教學:取得HTTP狀態碼的方法

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript與WebSocket:打造高效率的即時天氣預報系統

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

javascript如何使用insertBefore

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

如何在JavaScript中取得HTTP狀態碼的簡單方法

See all articles