我的WCF之旅(4):WCF中的序列化[下篇]
... ...續Part I([原創] 我的WCF之旅(4):WCF中的序列化(Serialization)- Part I)
XMLSerializer
提到XMLSerializer,我想絕大多數人都知道這是asmx采用的Serializer。首先我們還是來看一個例子,通過比較Managed Type的結構和生成的XML的結構來總結這種序列化方式采用的是怎樣的一種Mapping方式。和DataContractSerialzer Sample一樣,我們要定義用于序列化對象所屬的Type——XMLOrder和XMLProduct,他們和相面對應的DataContractOrder和DataContractProduct具有相同的成員。
using System;
using System.Collections.Generic;
using System.Text;
namespace Artech.WCFSerialization
{
public class XMLProduct
{
Private Fields
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Artech.WCFSerialization
{
public class XMLOrder
{
private Guid _orderID;
private DateTime _orderDate;
private XMLProduct _product;
private int _quantity;
Constructors
Properties
public override string ToString()
{
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
this._orderID,this._orderDate,this._product.ProductID,this._product.ProductName,this._product.ProducingArea,this._product.UnitPrice,this._quantity);
}
}
}
編寫Serialization的Code.
調用上面定義的方法,生成序列化的XML。
<?xml version="1.0" encoding="utf-8"?>
<XMLOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OrderID>b695fd18-9cd7-4792-968a-0c0c3a3962c2</OrderID>
<OrderDate>2007-03-09T00:00:00+08:00</OrderDate>
<Product>
<ProductID>23a2fe03-d0a0-4ce5-b213-c7e5196af566</ProductID>
<ProductName>Dell PC</ProductName>
<UnitPrice>4500</UnitPrice>
</Product>
<Quantity>300</Quantity>
</XMLOrder>
這里我們總結出以下的Mapping關系:
-
Root Element被指定為類名。
-
不會再Root Element中添加相應的Namaspace。
-
對象成員以XML Element的形式輸出。
-
對象成員出現的順利和在Type定義的順序一致。
-
只有Public Field和可讀可寫得Proppery才會被序列化到XML中——比如定義在XMLProduct中的internal string ProducingArea沒有出現在XML中。
-
Type定義的時候不需要運用任何Attribute。
以上這些都是默認的Mapping關系,同DataContractSerializer一樣,我們可以通過在Type以及它的成員中運用一些Attribute來改這種默認的Mapping。
-
Root Element名稱之后能為類名。
-
可以在Type上運用XMLRoot,通過Namaspace參數在Root Element指定Namespace。
-
可以通過在類成員上運用XMLElement Attribute和XMLAttribute Attribute指定對象成員轉化成XMLElement還是XMLAttribute。并且可以通過NameSpace參數定義Namespace。
-
可以在XMLElement或者XMLAttribute Attribute 通過Order參數指定成員在XML出現的位置。
-
可以通過XmlIgnore attribute阻止對象成員被序列化。
基于上面這些,我們重新定義了XMLProduct和XMLOrder。
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace Artech.WCFSerialization
{
public class XMLProduct
{
Private Fields
Constructors
Properties
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace Artech.WCFSerialization
{
[XmlRoot(Namespace = "http://artech.wcfSerialization/Samples/Order")]
public class XMLOrder
{
private Guid _orderID;
private DateTime _orderDate;
private XMLProduct _product;
private int _quantity;
Constructors
Properties
public override string ToString()
{
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
this._orderID,this._orderDate,this._product.ProductID,this._product.ProductName,this._product.ProducingArea,this._product.UnitPrice,this._quantity);
}
}
}
重新進行一次Serialization。我們可以得到下面的XML。
<?xml version="1.0" encoding="utf-8"?>
<XMLOrder id="9a0bbda4-1743-4398-bc4f-ee216e02695b" xmlns="http://artech.wcfSerialization/Samples/Order" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<product id="4e3aabe5-3a51-4000-9fd8-d821d164572a" xmlns="Http://Artech.WCFSerialization/Samples/Product">
<name>Dell PC</name>
<producingArea>Xiamen FuJian</producingArea>
<price>4500</price>
</product>
<quantity>300</quantity>
<date>2007-03-09T00:00:00+08:00</date>
</XMLOrder>
分析完XMLSerializer的Serialization功能,我們照例來分析它的反向過程—Deserialization。下面的Deserialization的Code。
調用DeserializeViaXMLSerializer,得到下面的Screen Shot。下面顯示的Order對象的信息和我們利用DataContractSerializaer進行Deserialization是的輸出沒有什么兩樣。不過有趣的是上面多出了兩行額外的輸出:The constructor of XMLProduct has been invocated! The constructor of XMLOrder has been invocated。而這個操作實際上是定義在XMLProduct和XMLOrder的默認(無參)構造函數里的。所此我們可以得出這樣的結論——用XMLSerializer進程Deserialization,會調用的默認(無參)構造函數來初始化對象。

DataContractSerializer V.S. XMLSerializer
上面我們分別分析了兩種不同的Serializer,現在我們來簡單總結一下他們的區別:
|
特性 |
XMLSerializer |
DataContractSerializer |
|
默認Mapping |
所有Public Field和可讀可寫Property |
所有DataMember Filed、Property |
|
是否需要Attribute |
不需要 |
DataContract DataMember或者Serializable |
|
成員的默認次序 |
Type中定義的順序 |
字母排序 |
|
兼容性 |
.asmx |
Remoting |
|
Deserialzation |
調用默認構造函數 |
不會調用 |
WCF相關內容:
[原創]我的WCF之旅(1):創建一個簡單的WCF程序
[原創]我的WCF之旅(2):Endpoint Overview
[原創]我的WCF之旅(3):在WCF中實現雙向通信(Bi-directional Communication)
[原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I
[原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part II
[原創]我的WCF之旅(5):Service Contract中的重載(Overloading)
[原創]我的WCF之旅(6):在Winform Application中調用Duplex Service出現TimeoutException的原因和解決方案
[原創]我的WCF之旅(7):面向服務架構(SOA)和面向對象編程(OOP)的結合——如何實現Service Contract的繼承
[原創]我的WCF之旅(8):WCF中的Session和Instancing Management
[原創]我的WCF之旅(9):如何在WCF中使用tcpTrace來進行Soap Trace
[原創]我的WCF之旅(10): 如何在WCF進行Exception Handling
[原創]我的WCF之旅(11):再談WCF的雙向通訊-基于Http的雙向通訊 V.S. 基于TCP的雙向通訊
[原創]我的WCF之旅(12):使用MSMQ進行Reliable Messaging
[原創]我的WCF之旅(13):創建基于MSMQ的Responsive Service


從WCF的全稱來分析——Windows Communication Foundation,顧名思義,他就是解決分布式互聯系統中各相互獨立的子系統如何交互的問題,換句話說,它實際上就是提供 一個基礎構架(Infrastructure)實現Application的通信問題。我們前邊已經提到,各個子系統之間是通過XML Message進行交互的,所以我們可以 把WCF看成是一個完全處理XML Message的構架,WCF的所有的功能都是圍繞著Message來展開的——如何把一個Service的調用轉或稱一個Message Exchange(Service Contract);如何實現一般的.NET對象和能夠容納于XML Message中的XML Infoset之間的轉化(Serialization和Deserialization);如何實現承載數據的XML Infoset和能夠用于網絡傳遞的字節流(Byte St


浙公網安備 33010602011771號