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

作者:逆心 时间:2024-02-25 17:46:14 

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; }
}

来源:http://www.cnblogs.com/kissdodog/archive/2013/01/25/2875936.html

标签:js,序列化,反序列化
0
投稿

猜你喜欢

  • Python用HBuilder创建交流社区APP

    2023-08-27 13:22:19
  • 关于mysql 的时间类型选择

    2024-01-17 11:44:20
  • VSCode 格式化缩进代码的实现

    2023-01-22 15:22:49
  • 深入浅析ASP在线压缩access数据库的方法

    2024-01-25 16:09:11
  • Oracle 自增(auto increment) 或 标识字段的建立方法

    2009-03-06 11:15:00
  • ODBC连接数据库以SQLserver为例图文详解

    2024-01-13 04:07:43
  • 详解Go中Map类型和Slice类型的传递

    2024-04-23 09:47:03
  • go语言 全局变量和局部变量实例

    2024-04-26 17:18:56
  • Node.js原理阻塞和EventEmitter及其继承的运用实战

    2024-05-05 09:21:33
  • js不能获取隐藏的div的宽度只能先显示后获取

    2024-04-17 10:25:17
  • 使用python3实现操作串口详解

    2021-10-21 18:32:41
  • python将ip地址转换成整数的方法

    2022-10-17 23:40:23
  • Django 实现Admin自动填充当前用户的示例代码

    2021-12-23 17:37:26
  • Python+Turtle动态绘制一棵树实例分享

    2021-10-03 00:33:20
  • Python callable()函数用法实例分析

    2021-12-14 00:28:52
  • 移动网站开发:标记语言

    2010-06-08 13:42:00
  • python实现kmp算法的实例代码

    2022-07-19 15:07:16
  • 11个Python3字典内置方法大全与示例汇总

    2021-11-26 22:33:51
  • java 使用poi 导入Excel数据到数据库的步骤

    2024-01-19 11:21:34
  • GoLand一键上传项目到远程服务器的方法步骤

    2024-04-26 17:33:15
  • asp之家 网络编程 m.aspxhome.com