進階系列(3)—— 序列化與反序列化

一 、序列化與反序列化的介紹

     序列化將對象轉換成字節流的過程,這樣就能夠輕鬆將對象保存在磁盤文件或數據庫中。javascript

     反序列化:序列化的逆過程,就是將字節流轉換回原來的對象的過程。前端

     把對象轉換爲字節序列的過程稱爲對象的序列化。把字節序列恢復爲對象的過程稱爲對象的反序列化。兩個環節爲可逆性的。java

二 、序列化的方法

   先看一個例子,咱們經過例子更加直觀的對其進行了解。咱們定義一個Person類,裏面定義了一些字段,在Main方法中實例化一個對象。咱們對person對象進行序列化與反序列化操做git

  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進行序列化github

注意添加對using System.Web.Script.Serialization的引用,使用此引用,須要首先引入System.Web.Extensions.dll文件。數據庫

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

(二)、Json.net直接使用提供的靜態成員JsonConvert.SerializeObject進行序列化json

  string newtostr = JsonConvert.SerializeObject(person);

上面紅色框爲JavaScriptSerializer的結果,下面綠色框爲Json.net的結果,這裏須要注意幾個地方:數組

一、 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");
});

二、Json.net默認生成的日期也不方便客戶端閱讀,須要簡單的處理一下:ui

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

三、JavaScriptSerializer序列化會對特殊字符(如<>等)進行編碼,好比上面的\u003c \u003e,不少人看到這個的時候,第一感受就是太扯蛋了,接下來就是各類百度,怎麼把這個轉成正常的」<>」。實際上你不用作任何操做,這是標準的JS編碼方式,前端會自行處理這個問題。好比:

<script type="text/javascript">
    var str = 'yubaolee <yubaolee>'
    var str2 = 'yubaolee \u003cyubaolee\u003e';
    alert(str == str2);  //結果爲true
</script>

附:若是你真的不明白\u003c這究竟是個什麼玩意,請移步:字符編碼。

3、 反序列化的方法

慣例依舊,咱們先上一段代碼,此部分代碼是對上一段代碼的再進行。

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

4、 幾種方式效率的對比

詳細對比過程請參閱:https://github.com/kevin-montrose/Jil

5、 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,該方法會拋出錯誤。

相關文章
相關標籤/搜索