天天看點

WCF序列化

在WCF中,提供了專門用來序列化和反序列操作的類,該類就是DataContractSerializer類。一般而言,WCF會自動選擇使用DataContractSerializer來對可序列話資料契約進行序列化,不需要開發者直接調用。WCF除了支援DataContractSerializer類來進行序列化外,還支援另外兩種序列化器,這兩種序列化器分别為:XMLSerializer(定義在System.XML.Serialization namespace)和NetDataContractSerializer (定義在System.XML.Serialization namespace)。XmlSerializer類不是WCF專用的類,Asp.net Web服務統一使用該類作為序列化器,但XmlSerializer類支援的類少于DataContractSerializer列支援的類型,但它允許對生成的XML進行更多的控制,并且支援更多的XML架構定義語言(XSD)标準。它不需要在可序列化類上有任何聲明性的屬性。

DataContractSerializer類與NetDataContractSerializer類類似,它們之間主要的差別在于:在使用NetDataContractSerializer進行序列化時,不需要指定序列化的類型,如:

aNetDataContractSerializer serializer =
    new NetDataContractSerializer();  // 不需要明确指定序列化的類型
serializer.WriteObject(writer, p);

// 而使用DataContractSerializer需要明确指定序列化的類型
DataContractSerializer serializer =
            new DataContractSerializer(typeof(Order)); // 需要明确指定序列化的類型
        serializer.WriteObject(writer, p);

      

使用DataContractSerializer類生成的XML檔案與原始對象之間的映射關系如下(預設情況):

1. Root Element為對象的Type Name——DataContractOrder

2. Type的Namespace會被加到XML根節點的Namespace中

3. 對象的所有成員以XML Element的形式而不是以XML Attribute的形式輸出。

4. 是以對象在XML的輸出順序是按照字母排序。

5. 所有成員的Elelement 名稱為成員名稱。

6. 不論成員設定怎樣的作用域(public,protected,internal,甚至市Private),

所有運用了DataMemberAttribute的成員均被序列化到XML中,

7. Type和成員必須運用DataContractAttribute和DataMemberAttribute才能被序列化。

可以通過這兩個Attribute(DataContractAttribute和DataMemberAttribute)制定相關的參數來生成所需的XML 結構

1. Root Element可以通過DataContractAttribute中的Name參數定義。

2. Namespace可以通過DataContractAttribute中的NameSpace參數定義。

3. 對象的成員隻能以XML Element的形式被序列化。

4. 對象成員對應的XML Element在XML出現的位置可以通過DataMemberAttribute的Order參數來定義。

5. 對象成員對應的Element的名稱可以通過DataMemberAttribute中的Name定義。

6. 如果不希望某個成員輸出到XML中,可以去掉成員對應的DataMemberAttribute Attribute。

此外DataMemberAttribute還有連個額外的參數:

1. IsRequired:制定該成員為必須的,如果通過工具生成XSD的話,對應的Element的minOccur=“1”

2. EmitDefaultValue:制定是否輸入沒有指派的成員(值為預設值)是否出現在XML中。

注:因為WCF中使用DataContractSerializer進行序列化和反序列化的,由于DataContractSerializer進行序列化和反序列化時,都必須事先确定對象的類型。如果被序列化對象或反序列化生成的對象包含不可知的類型,序列化或反序列化将失敗。是以為了保證DataContractSerializer正常的序列化和反序列化,需要将“未知”類型加入DataContractSerializer“已知”類型清單中。可以通過兩個特性設定:KnownTypeAttribute和ServiceKnownTypeAttribute。KnownTypeAttribute應用于資料契約中,用于設定繼承于該資料契約類型的子資料契約,或引用其他的契約類型。ServiceKnownTypeAttribute既可以應用于服務契約的接口和方法上,還可以應用在服務實作的類和方法上,應用在不同的目标元素,決定了定義已知類型的作用範圍

使用XmlSerializer類生成的XML檔案與原始對象之間的映射關系如下(預設情況):

1.Root Element被指定為類名。

2.不會再Root Element中添加相應的Namaspace。

3.對象成員以XML Element的形式輸出。

4.對象成員出現的順利和在Type定義的順序一緻。

5.隻有Public Field和可讀可寫得Proppery才會被序列化到XML中——比如定義在XMLProduct中的internal string ProducingArea沒有出現在XML中。

6.Type定義的時候不需要運用任何Attribute。

可以通過XML相關的一些Attribute來生成所需的XML 結構

1.Root Element名稱之後能為類名。

2.可以在Type上運用XMLRoot,通過Namaspace參數在Root Element指定Namespace。

3.可以通過在類成員上運用XMLElement Attribute和XMLAttribute Attribute指定對象成員轉化成XMLElement還是XMLAttribute。并且可以通過NameSpace參數定義4.Namespace。

5.可以在XMLElement或者XMLAttribute Attribute 通過Order參數指定成員在XML出現的位置。

6.可以通過XmlIgnore attribute阻止對象成員被序列化。

兩種不同的Serializer差別:

特性 XMLSerializer DataContractSerializer
預設Mapping 所有Public Field和可讀可寫Property 所有DataMember Filed、Property
是否需要Attribute 不需要 DataContract DataMember或者Serializable
成員的預設次序 Type中定義的順序 字母排序
相容性 .asmx Remoting
Deserialzation 調用預設構造函數 不會調用

該篇文章參考和引用了以下作者的文章内容:

我的WCF之旅(4):WCF中的序列化[上篇]

我的WCF之旅(4):WCF中的序列化[下篇]

跟我一起學WCF(7)——WCF資料契約與序列化詳解

文章同步發表于我的個人網站:http://www.zuowenjun.cn/post/2015/03/25/134.html