[.net 物件導向程式設計進階] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

yubinfeng發表於2015-07-10

[.net 物件導向程式設計進階] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

本節導讀:

介紹JSON的結構,在JS中的使用。重點說明JSON如何在.NET中快帶序列化和反序列化。最後介紹在使用.NET序列化JSON過程中的注意事項。

讀前必備:

A.泛型       [.net 物件導向程式設計基礎]  (18) 泛型

B.LINQ使用  [.net 物件導向程式設計基礎] (20) LINQ使用

1. 關於JSON

JSON的全稱是”JavaScript Object Notation”,意思是JavaScript物件表示法,它是一種基於文字,獨立於語言的輕量級資料交換格式。

2. 為什麼要使用JSON

我們上節說的XML雖然也是一種通用的跨平臺資料交換格式,為什麼不用呢?

A.在Javascript中序列化和反序列化XML相當不方便。而Js中JSON可以非常方便的反序列化為物件。

B.在移動應用中,XML擁有過多的標記,比較佔用流量,而JSON幾乎沒有任何標記。

3. JSON兩種格式

JSON有兩種格式:物件和陣列(集合)

我們先看一下這兩種格式:

物件:

{
    "kongfuName": "獨孤九劍",
    "lethality": 100
}

陣列(集合):

[
    {
        "kongfuName": "獨孤九劍",
        "lethality": 100
    },
    {
        "kongfuName": "易筋經",
        "lethality": 100
    }
]

4. JSON字串

JSON字串,就是將符合以上兩種格式的字串

如:var jsonStr=”[{'kongfuName':'獨孤九劍','lethality':100},{'kongfuName':'易筋經','lethality':100}]”;

5. Javasctip中反序列化JSON

JQuery中提供的反序列化方法:

var obj = jQuery.parseJSON('{"name":"John"}');alert( obj.name === "John" );

6. .NET自帶的兩種JSON序列化

下面分別舉例說明,還是採用我們之前的“武林大俠”“武功”實體類為例,先定義兩個類,如下:

兩個類定義:

/// <summary>
/// 類:武林高手
/// MartialArtsMaster
/// </summary>
[DataContract]
public  class MartialArtsMaster
{
    [DataMember]
    /// <summary>
    /// 編號
    /// </summary>
    public int id { get; set; }
    [DataMember]
    /// <summary>
    /// 姓名
    /// </summary>
    public string name { get; set; }
    [DataMember]
    /// <summary>
    /// 年齡
    /// </summary>
    public int age { get; set; }
    [DataMember]
    /// <summary>
    /// 門派
    /// </summary>
    public string menpai { get; set; }
    [DataMember]
    /// <summary>
    /// 武學
    /// </summary>
    public List<Kongfu> kongFu { get; set; }
             
    /// <summary>
    /// 級別
    /// </summary>
    public int level { get; set; }
}

/// <summary>
/// 類:武學
/// Kongfu
/// </summary>
[DataContract]
public class Kongfu
{
    [DataMember]
    /// <summary>
    /// 武學名稱
    /// </summary>
    public string kongfuName { get; set; }

    [DataMember]
    /// <summary>
    /// 殺傷力
    /// </summary>
    public int lethality { get; set; }
}

增加幾個武林高手:

List<MartialArtsMaster> masterList = new List<MartialArtsMaster>();
//增加幾個武林高手
masterList.Add(new MartialArtsMaster()
{
    id = 1,
    name = "令狐沖",
    age = 23,
    menpai = "華山",
    kongFu = new List<Kongfu>() { new Kongfu() { kongfuName = "獨孤九劍", lethality = 100 }, new Kongfu() { kongfuName = "易筋經", lethality = 100 } },
    level = 10
});

masterList.Add(new MartialArtsMaster()
{
    id = 2,
    name = "黃藥師",
    age = 55,
    menpai = "桃花島",
    kongFu = new List<Kongfu>() { new Kongfu() { kongfuName = "彈指神通", lethality = 100 } },
    level = 10
});

masterList.Add(new MartialArtsMaster()
{
    id = 3,
    name = "段譽",
    age = 20,
    menpai = "天龍寺",
    kongFu = new List<Kongfu>() { new Kongfu() { kongfuName = "凌波微步", lethality = 100 }, new Kongfu() { kongfuName = "六脈神劍", lethality = 100 } },
    level = 10
});

masterList.Add(new MartialArtsMaster()
{
    id = 4,
    name = "喬峰",
    age = 33,
    menpai = "丐幫",
    kongFu = new List<Kongfu>() { new Kongfu() { kongfuName = "降龍十八掌", lethality = 100 }, new Kongfu() { kongfuName = "打狗棒法", lethality = 100 } },
    level = 10
});

6.1  DataContractJsonSerializer

程式集:System.Runtime.Serialization.dll

名稱空間 System.Runtime.Serialization.Josn

類:DataContractJsonSerializer

6.1.1  DataContractJsonSerializer 序列化  

//程式集:System.Runtime.Serialization.dll
//名稱空間 System.Runtime.Serialization.Josn
//類:DataContractJsonSerializer
System.Runtime.Serialization.Json.DataContractJsonSerializer masterJson = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(List<MartialArtsMaster>));

           
string strJson = String.Empty;
//序列化
using (MemoryStream stream = new MemoryStream())
{
    masterJson.WriteObject(stream, masterList);
    strJson = Encoding.UTF8.GetString(stream.ToArray());
}
Console.WriteLine(strJson);

 執行結果如下:

注意:此種序列化,需要給類加上標記 

6.1.2  DataContractJsonSerializer反序列化  

//反序列化
List<MartialArtsMaster> newMasterList = new List<MartialArtsMaster>();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strJson)))
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<MartialArtsMaster>));
    newMasterList = (List<MartialArtsMaster>)serializer.ReadObject(ms);
}
string result = String.Empty;           

Func<List<Kongfu>,string> kongFu = delegate (List<Kongfu> kongfu) { string kflist = String.Empty; kongfu.ForEach(m => kflist += "武功名稱:" + m.kongfuName + ";殺傷力" + m.lethality+"\n"); return kflist; };
newMasterList.ForEach(m => result += "大俠編號:" + m.id + " 大俠名字:" + m.name + " 年齡:" + m.age + " 門派:" + m.menpai + " \n所學武功:\n" + kongFu(m.kongFu));

Console.WriteLine(result);

 執行結果如下:

6.2 Serialization,Deserialize

程式集:System.Web.Extensions.dll

名稱空間:System.Web.Script.Serialization

類:Serialization,Deserialize

6.2.1 Serialization 序列化 

//程式集:System.Web.Extensions.dll
//名稱空間:System.Web.Script.Serialization
//類:Serialization,Deserialize
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
//執行序列化
string strJson2 = jsonSerializer.Serialize(masterList);
Console.WriteLine(strJson2);

 執行結果如下:

 6.2.2 Deserialize 反序列化 

//執行反序列化     
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
List<MartialArtsMaster> newMasterList = jsonSerializer.Deserialize<List<MartialArtsMaster>> (strJson2);
string result = String.Empty;

Func<List<Kongfu>, string> kongFu = delegate (List<Kongfu> kongfu) { string kflist = String.Empty; kongfu.ForEach(m => kflist += "武功名稱:" + m.kongfuName + ";殺傷力" + m.lethality + "\n"); return kflist; };
newMasterList.ForEach(m => result += "大俠編號:" + m.id + " 大俠名字:" + m.name + " 年齡:" + m.age + " 門派:" + m.menpai + " \n所學武功:\n" + kongFu(m.kongFu));

Console.WriteLine(result);

 執行結果如下:

 7. 注意事項:

可以使用IgnoreDataMember:指定該成員不是資料協定的一部分且沒有進行序列化

DataMember:定義序列化屬性引數

使用DataMember屬性標記欄位必須使用DataContract標記類否則DataMember標記不起作用。

預設情況下,不允許序列化。因此使用上述類進行序列化或反序列化時,一定要給類加上標記[DataContract]。

而使用第DataContractJsonSerializer,則不需要。

因此:

使用類:Serialization,Deserialize(名稱空間:System.Web.Script.Serialization),可以實現快速序列化。

使用類:DataContractJsonSerializer,可以通過標記那些屬性或欄位需要序列化,進行區域性序列化。

8.本節要點:

A.認識JSON:Javascript表示法,一種跨平臺、輕量級資料交換格式;

B.認識JSON的兩種格式

C.掌握在JS中使用JSON

D.掌握使用.NET自帶的兩個類進行JSON序列化和反序列化

使用類:Serialization,Deserialize(名稱空間:System.Web.Script.Serialization),可以實現快速序列化。

使用類:DataContractJsonSerializer,可以通過標記那些屬性或欄位需要序列化,進行區域性序列化。

==============================================================================================  

 返回目錄

 <如果對你有幫助,記得點一下推薦哦,如有有不明白或錯誤之處,請多交流>  

<對本系列文章閱讀有困難的朋友,請先看《.net 物件導向程式設計基礎》>

<轉載宣告:技術需要共享精神,歡迎轉載本部落格中的文章,但請註明版權及URL>

.NET 技術交流群:467189533    .NET 程式設計

==============================================================================================   

相關文章