浅析JavaScriptSerializer类的序列化与反序列化


Posted in Javascript onNovember 22, 2016

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

<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="确认" />
</body>
</html>

试下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,"关羽",21);
   //string json = jss.Serialize(p);  //将对象序列化成Json字符串 //此处报异常使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值。

   jss.MaxJsonLength = 2097152;
   
   //序列化
   string json = jss.Serialize(p); 
   Console.WriteLine(json); //输出 {"Id":1,"Name":"关羽","Age":21}`这就是Json格式了

   //反序列化Deserialize
   Person p2 = jss.Deserialize<Person>("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}");
   Console.WriteLine(p2.Id + " " + p2.Name + " " + p2.Age); //输出 1 关羽 21
   //Deserialize的非泛型写法
   Person p3 = jss.Deserialize("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}",typeof(Person)) as Person; //注意这个方法返回的是object类,因此要强制转换成Person类
   Console.WriteLine(p3.Id + " " + p3.Name + " " + p3.Age); //同样输出 1 关羽 21

   object obj = jss.DeserializeObject("{\"Id\":1,\"Name\":\"关羽\",\"Age\":21}"); //将Json字符转换为Object类型
   //Person p4 = obj as Person; //此行代码转为的p4为null
   Person p4 = jss.ConvertToType<Person>(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("Id");
   dt.Columns.Add("Name");
   dt.Columns.Add("Age");
   dt.Rows.Add(1, "关羽", 21);
   dt.Rows.Add(2, "刘备", 22);
   dt.Rows.Add(3, "张飞", 20);

   JavaScriptSerializer jss = new JavaScriptSerializer();
   //注册转换器的方法,用于复杂转换除了实现还需要注册到JavaScriptSerializer
   jss.RegisterConverters(new JavaScriptConverter[] { new DataTableConverter() });

   string strJson = 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>
 /// DataTable JSON转换类
 /// </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>
  /// 获取本转换器支持的类型
  /// </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); //默认的序列化层次是100

   Person p1 = new Person(1, "刘备", 24);
   p1.p = new Person(2, "关羽", 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":"关羽","Age":23,"p":{"Id":3,"Name":"张飞","Age":21,"p":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,"刘备",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; }
 }

以上就是本文的全部内容,希望对大家有所帮助,谢谢对三水点靠木的支持!

Javascript 相关文章推荐
JQquery的一些使用心得分享
Aug 01 Javascript
javascript full screen 全屏显示页面元素的方法
Sep 27 Javascript
JS简单实现元素复制示例附图
Nov 19 Javascript
浅析JavaScript原型继承的陷阱
Dec 03 Javascript
jQuery UI设置固定日期选择特效代码分享
Aug 27 Javascript
node.js平台下利用cookie实现记住密码登陆(Express+Ejs+Mysql)
Apr 26 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
Nov 02 Javascript
JavaScript中call和apply方法的区别实例分析
Aug 03 Javascript
Vue创建头部组件示例代码详解
Oct 23 Javascript
vue将后台数据时间戳转换成日期格式
Jul 31 Javascript
vue项目创建步骤及路由router
Jan 14 Javascript
pnpm对npm及yarn降维打击详解
Aug 05 Javascript
JS如何设置iOS中微信浏览器的title
Nov 22 #Javascript
原生JS查找元素的方法(推荐)
Nov 22 #Javascript
自己封装的一个原生JS拖动方法(推荐)
Nov 22 #Javascript
SelecT下拉框选中和取值的解决方法
Nov 22 #Javascript
javascript入门之window对象【新手必看】
Nov 22 #Javascript
AngularJS实现DOM元素的显示与隐藏功能
Nov 22 #Javascript
JavaScript ES6中CLASS的使用详解
Nov 22 #Javascript
You might like
MySQL GBK→UTF-8编码转换
2007/05/24 PHP
用php或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
PHP的5个安全措施小结
2012/07/17 PHP
关于php中一些字符串总结
2016/05/05 PHP
JavaScript 滚轮事件使用说明
2010/03/07 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
jQuery中on()方法用法实例
2015/01/19 Javascript
js获取域名的方法
2015/01/27 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
angularJS 如何读写缓冲的方法(推荐)
2016/08/06 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
Vue2.0实现购物车功能
2017/06/05 Javascript
关于Ajax的原理以及代码封装详解
2017/09/08 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
2018/01/17 Javascript
Vue多种方法实现表头和首列固定的示例代码
2018/02/02 Javascript
vue单页应用的内存泄露定位和修复问题小结
2019/08/02 Javascript
小程序使用分包的示例代码
2020/03/23 Javascript
js 动态校验开始结束时间的实现代码
2020/05/25 Javascript
Python中的字典与成员运算符初步探究
2015/10/13 Python
详解python中docx库的安装过程
2019/11/08 Python
python argparse模块通过后台传递参数实例
2020/04/20 Python
python request 模块详细介绍
2020/11/10 Python
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
LUISAVIAROMA德国官网:时尚奢侈品牌购物网站
2020/11/12 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
物业管理员岗位职责范文
2013/11/25 职场文书
大队干部竞选演讲稿
2014/04/28 职场文书
销售顾问工作计划书
2014/08/15 职场文书
奉献爱心演讲稿
2014/09/04 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
艺术节开幕词
2015/01/28 职场文书
教师年度考核个人总结
2015/02/12 职场文书
确保工程质量承诺书
2015/04/29 职场文书
2016年大学校运会广播稿件
2015/12/21 职场文书
Netty结合Protobuf进行编解码的方法
2021/06/26 Java/Android