我的WCF之旅(4):WCF中的序列化[下篇]
... ...續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#region?Private?Fields
????????private?Guid?_productID;
????????private?string?_productName;
????????private?string?_producingArea;
????????private?double?_unitPrice;
???????
????????Constructors#region?Constructors
????????public?XMLProduct()
????????{
????????????Console.WriteLine("The?constructor?of?XMLProduct?has?been?invocated!");
????????}
????????public?XMLProduct(Guid?id,?string?name,?string?producingArea,?double?price)
????????{
????????????this._productID?=?id;
????????????this._productName?=?name;
????????????this._producingArea?=?producingArea;
????????????this._unitPrice?=?price;
????????}
????????#endregion
????????Properties#region?Properties
????????public?Guid?ProductID
????????{
????????????get?{?return?_productID;?}
????????????set?{?_productID?=?value;?}
????????}
????????public?string?ProductName
????????{
????????????get?{?return?_productName;?}
????????????set?{?_productName?=?value;?}
????????}
????????internal?string?ProducingArea
????????{
????????????get?{?return?_producingArea;?}
????????????set?{?_producingArea?=?value;?}
????????}
????????public?double?UnitPrice
????????{
????????????get?{?return?_unitPrice;?}
????????????set?{?_unitPrice?=?value;?}
????????}
???????#endregion
????}
}
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#region?Constructors
????????public?XMLOrder()
????????{
????????????this._orderID?=?new?Guid();
????????????this._orderDate?=?DateTime.MinValue;
????????????this._quantity?=?int.MinValue;
????????????Console.WriteLine("The?constructor?of?XMLOrder?has?been?invocated!");
????????}
????????public?XMLOrder(Guid?id,?DateTime?date,?XMLProduct?product,?int?quantity)
????????{
????????????this._orderID?=?id;
????????????this._orderDate?=?date;
????????????this._product?=?product;
????????????this._quantity?=?quantity;
????????}
????????#endregion
????????Properties#region?Properties
????????public?Guid?OrderID
????????{
????????????get?{?return?_orderID;?}
????????????set?{?_orderID?=?value;?}
????????}
????????public?DateTime?OrderDate
????????{
????????????get?{?return?_orderDate;?}
????????????set?{?_orderDate?=?value;?}
????????}
????????public?XMLProduct?Product
????????{
????????????get?{?return?_product;?}
????????????set?{?_product?=?value;?}
????????}
????????public?int?Quantity
????????{
????????????get?{?return?_quantity;?}
????????????set?{?_quantity?=?value;?}
????????}
????????#endregion
????????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.
?
static?void?SerializeViaXMLSerializer()
????????{
????????????XMLProduct?product?=?new?XMLProduct(Guid.NewGuid(),?"Dell?PC",?"Xiamen?FuJian",?4500);
????????????XMLOrder?order?=?new?XMLOrder(Guid.NewGuid(),?DateTime.Today,?product,?300);
????????????string?fileName?=?_basePath?+?"Order.XmlSerializer.xml";
????????????using?(FileStream?fs?=?new?FileStream(fileName,?FileMode.Create))
????????????{
????????????????XmlSerializer?serializer?=?new?XmlSerializer(typeof(XMLOrder));
????????????????using?(XmlDictionaryWriter?writer?=?XmlDictionaryWriter.CreateTextWriter(fs))
????????????????{
????????????????????serializer.Serialize(writer,?order);
????????????????}
????????????}
????????????Process.Start(fileName);
????????}
調用上面定義的方法,生成序列化的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關系:
以上這些都是默認的Mapping關系,同DataContractSerializer一樣,我們可以通過在Type以及它的成員中運用一些Attribute來改這種默認的Mapping。
基于上面這些,我們重新定義了XMLProduct和XMLOrder。
using?System;using?System.Collections.Generic;
using?System.Text;
using?System.Xml.Serialization;
namespace?Artech.WCFSerialization
{
????public?class?XMLProduct
????{
????????Private?Fields#region?Private?Fields
????????private?Guid?_productID;
????????private?string?_productName;
????????private?string?_producingArea;
????????private?double?_unitPrice;
????????#endregion
????????Constructors#region?Constructors
????????public?XMLProduct()
????????{
????????????Console.WriteLine("The?constructor?of?XMLProduct?has?been?invocated!");
????????}
????????public?XMLProduct(Guid?id,?string?name,?string?producingArea,?double?price)
????????{
????????????this._productID?=?id;
????????????this._productName?=?name;
????????????this._producingArea?=?producingArea;
????????????this._unitPrice?=?price;
????????}
????????#endregion
????????Properties#region?Properties
????????[XmlAttribute("id")]
????????public?Guid?ProductID
????????{
????????????get?{?return?_productID;?}
????????????set?{?_productID?=?value;?}
????????}
????????[XmlElement("name")]
????????public?string?ProductName
????????{
????????????get?{?return?_productName;?}
????????????set?{?_productName?=?value;?}
????????}
????????[XmlElement("producingArea")]
????????public?string?ProducingArea
????????{
????????????get?{?return?_producingArea;?}
????????????set?{?_producingArea?=?value;?}
????????}
????????[XmlElement("price")]
????????public?double?UnitPrice
????????{
????????????get?{?return?_unitPrice;?}
????????????set?{?_unitPrice?=?value;?}
????????}
#endregion
????}
}
?
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#region?Constructors
????????public?XMLOrder()
????????{
????????????this._orderID?=?new?Guid();
????????????this._orderDate?=?DateTime.MinValue;
????????????this._quantity?=?int.MinValue;
????????????Console.WriteLine("The?constructor?of?XMLOrder?has?been?invocated!");
????????}
????????public?XMLOrder(Guid?id,?DateTime?date,?XMLProduct?product,?int?quantity)
????????{
????????????this._orderID?=?id;
????????????this._orderDate?=?date;
????????????this._product?=?product;
????????????this._quantity?=?quantity;
????????}
????????#endregion
????????Properties#region?Properties
????????[XmlAttribute("id")]
????????public?Guid?OrderID
????????{
????????????get?{?return?_orderID;?}
????????????set?{?_orderID?=?value;?}
????????}
????????[XmlElement(ElementName?=?"date",Order?=?3)]
????????public?DateTime?OrderDate
????????{
????????????get?{?return?_orderDate;?}
????????????set?{?_orderDate?=?value;?}
????????}
????????[XmlElement(ElementName?=?"product",?Order?=?1,?Namespace?=?"Http://Artech.WCFSerialization/Samples/Product")]
????????public?XMLProduct?Product
????????{
????????????get?{?return?_product;?}
????????????set?{?_product?=?value;?}
????????}
????????[XmlElement(ElementName?=?"quantity",?Order?=?2)]
????????public?int?Quantity
????????{
????????????get?{?return?_quantity;?}
????????????set?{?_quantity?=?value;?}
????????}
????????#endregion
????????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。
?
static?void?DeserializeViaXMLSerializer()
????????{
???????????string?fileName?=?_basePath?+?"Order.XmlSerializer.xml";
???????????XMLOrder?order;
???????????using?(FileStream?fs?=?new?FileStream(fileName,?FileMode.Open))
????????????{
????????????????XmlSerializer?serializer?=?new?XmlSerializer(typeof(XMLOrder),?"http://artech.WCFSerialization/Samples");
????????????????using?(XmlDictionaryReader?reader?=?XmlDictionaryReader.CreateTextReader(fs,?new?XmlDictionaryReaderQuotas()))
????????????????{
????????????????????order=?serializer.Deserialize(reader)?as?XMLOrder;
????????????????}
????????????}
????????????Console.WriteLine(order);
????????????Console.Read();
}
調用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 | 調用默認構造函數 | 不會調用 |
?
作者:Artech出處:http://artech.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
總結
以上是生活随笔為你收集整理的我的WCF之旅(4):WCF中的序列化[下篇]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css自适应的圆
- 下一篇: Oracle创建表空间及用户