• 进阶系列(3)—— 序列化与反序列化


    一 、序列化与反序列化的介绍

         序列化将对象转换成字节流的过程,这样就可以轻松将对象保存在磁盘文件或数据库中。

         反序列化:序列化的逆过程,就是将字节流转换回原来的对象的过程。

         把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。两个环节为可逆性的。

    二 、序列化的方法

       先看一个例子,我们通过例子更加直观的对其进行了解。我们定义一个Person类,里面定义了一些字段,在Main方法中实例化一个对象。我们对person对象进行序列化与反序列化操作

      public class Person
        {
            public string Name;
            public int Age;
            public Guid TokenId;
            public DateTime RegTime;
            public Person Child;
            public Person Friend;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var person = new Person
                {
                    Name = "张三<zhangsan>",
                    Age = 12,
                    TokenId = Guid.NewGuid(),
                    Child = new Person
                    {
                        Age = 1,
                        Name = "小张",
                        RegTime = DateTime.Now,
                        TokenId = Guid.NewGuid()
                    }
                };
    
                //序列化
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                Console.WriteLine("使用 JavaScriptSerializer序列化");
                var jsstr = serializer.Serialize(person);  //使用 JavaScriptSerializer序列化
                Console.WriteLine(jsstr);
    
    
                Console.WriteLine("使用 JsonConvert序列化"); 
                string newtostr = JsonConvert.SerializeObject(person, Formatting.Indented,
                    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });//使用 JsonConvert序列化
    
                Console.WriteLine(newtostr);
                Console.ReadLine();
            }
        }

    (一)、JavaScriptSerializer序列化是先生成一个对象,然后调用它的成员函数Serialize进行序列化

    注意添加对using System.Web.Script.Serialization的引用,使用此引用,需要首先引入System.Web.Extensions.dll文件。

    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var jsstr = serializer.Serialize(person);  

    (二)、Json.net直接使用提供的静态成员JsonConvert.SerializeObject进行序列化

      string newtostr = JsonConvert.SerializeObject(person);

    上面红色框为JavaScriptSerializer的结果,下面绿色框为Json.net的结果,这里需要注意几个地方:

    1、 JavaScriptSerializer序列化后的时间格式:"/Date(1441813200214)/" 表示的是1970年1月1日(DateTime的最小值)到date实际表示的日期之差的总毫秒数。通常我们需要把它转成标准的时间格式。可以用下面的方法进行字符串处理:

    jsstr = Regex.Replace(jsstr, @"\/Date((d+))\/", match =>
    {
        DateTime dt = new DateTime(1970, 1, 1);
        dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
        dt = dt.ToLocalTime();
        return dt.ToString("yyyy-MM-dd HH:mm:ss");
    });

    2、Json.net默认生成的日期也不方便客户端阅读,需要简单的处理一下:

    string newtonstr = JsonConvert.SerializeObject(p, Formatting.Indented,
                    new IsoDateTimeConverter() {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"});

    3、JavaScriptSerializer序列化会对特殊字符(如<>等)进行编码,比如上面的u003c u003e,很多人看到这个的时候,第一感觉就是太扯蛋了,接下来就是各种百度,怎么把这个转成正常的”<>”。实际上你不用做任何操作,这是标准的JS编码方式,前端会自行处理这个问题。比如:

    <script type="text/javascript">
        var str = 'yubaolee <yubaolee>'
        var str2 = 'yubaolee u003cyubaoleeu003e';
        alert(str == str2);  //结果为true
    </script>

    附:如果你真的不明白u003c这到底是个什么玩意,请移步:字符编码。

    三、 反序列化的方法

    惯例依旧,我们先上一段代码,此部分代码是对上一段代码的再进行。

     public class Person
        {
            public string Name;
            public int Age;
            public Guid TokenId;
            public DateTime RegTime;
            public Person Child;
            public Person Friend;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var person = new Person
                {
                    Name = "张三<zhangsan>",
                    Age = 12,
                    TokenId = Guid.NewGuid(),
                    Child = new Person
                    {
                        Age = 1,
                        Name = "小张",
                        RegTime = DateTime.Now,
                        TokenId = Guid.NewGuid()
                    }
                };
    
                ////序列化
                //JavaScriptSerializer serializer = new JavaScriptSerializer();
                //Console.WriteLine("使用 JavaScriptSerializer序列化");
                //var jsstr = serializer.Serialize(person);  //使用 JavaScriptSerializer序列化
                //Console.WriteLine(jsstr);
                Console.WriteLine("使用 JsonConvert序列化"); 
                string newtostr = JsonConvert.SerializeObject(person, Formatting.Indented,
                    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });//使用 JsonConvert序列化
    
    //反序列化 JavaScriptSerializer serializer = new JavaScriptSerializer(); var objOne = serializer.Deserialize<Person>(newtostr); var objTwo = JsonConvert.DeserializeObject<Person>(newtostr);
    Console.WriteLine(newtostr); Console.ReadLine(); }

    (一)、使用JavaScriptSerializer方法进行反序列化

    JavaScriptSerializer serializer = new JavaScriptSerializer();
                var objOne = serializer.Deserialize<Person>(newtostr);

    (二)、使用JsonConvert方法进行反序列化

    var objTwo = JsonConvert.DeserializeObject<Person>(newtostr);

    四、 几种方式效率的对比

    详细对比过程请参阅:https://github.com/kevin-montrose/Jil

    五、 Json的定义

         谈到序列化与反序列,我们不得不提到一种运用非常广泛的数据格式:Json。在用.net处理的时候,我们经常用的都是序列化与反序列化,就是我们上面讲解的知识点,接下来我们会接着继续讲解Json数据格式,在前端的处理形式。

         JSON 的语法可以表示以下三种类型的值。
         简单值使用与 JavaScript 相同的语法,可以在 JSON 中表示字符串、数值、布尔值和 null。但 JSON 不支持 JavaScript 中的特殊值 undefined
         对象对象作为一种复杂数据类型,表示的是一组无序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值。
         数组数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组。Json不支持变量、函数或对象实例,它就是一种表示结构化数据的格式,虽然与 JavaScript 中表示数据的某些语法相同,但它并不局限于 JavaScript 的范畴。
    六 、JSON对象

    JSON对象有两个方法: stringify()parse()。在最简单的情况下,这两个方法分别用于把JavaScript 对象序列化为 JSON字符串和把 JSON字符串解析为原生 JavaScript 值。例如:

    var book = {
    title: "Professional JavaScript",
    authors: [
    "Nicholas C. Zakas"
    ],
    edition: 3,
    year: 2011
    };
    var jsonText = JSON.stringify(book);

    这个例子使用 JSON.stringify()把一个 JavaScript 对象序列化为一个 JSON 字符串,然后将它保存在变量 jsonText 中。默认情况下, JSON.stringify()输出的 JSON 字符串不包含任何空格字符或缩进,因此保存在 jsonText 中的字符串如下所示:

    {"title":"Professional JavaScript","authors":["Nicholas C. Zakas"],"edition":3,
    "year":2011} 

    JSON 字符串直接传递给 JSON.parse()就可以得到相应的 JavaScript 值。例如,使用下列代码就可以创建与 book 类似的对象:

    var bookCopy = JSON.parse(jsonText);

    注意,虽然 book bookCopy 具有相同的属性,但它们是两个独立的、没有任何关系的对象。如果传给 JSON.parse()的字符串不是有效的 JSON,该方法会抛出错误。

  • 相关阅读:
    css3 动画+动画库
    垃圾回收 及 内存泄漏
    做菜体会
    微信小程序
    微信公众号2
    JavaScript 原生事件
    Bootstrap框架
    Less 和 Sass
    HTML标签总结
    表单元素
  • 原文地址:https://www.cnblogs.com/wyh19941210/p/6775674.html
Copyright © 2020-2023  润新知