我的WCF之旅(4):WCF中的序列化[下篇]
... ...续Part I
XMLSerializer
提到XMLSerializer,我想绝大多数人都知道这是asmx采用的Serializer。首先我们还是来看一个例子,通过比较Managed Type的结构和生成的XML的结构来总结这种序列化方式采用的是怎样的一种Mapping方式。和DataContractSerialzer Sample一样,我们要定义用于序列化对象所属的Type——XMLOrder和XMLProduct,他们和相面对应的DataContractOrder和DataContractProduct具有相同的成员。
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text;
 namespace Artech.WCFSerialization
namespace Artech.WCFSerialization {
{ public class XMLProduct
    public class XMLProduct {
    { Private Fields
        Private Fields }
}
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text;
 namespace Artech.WCFSerialization
namespace Artech.WCFSerialization {
{ public class XMLOrder
    public class XMLOrder {
    { private Guid _orderID;
        private Guid _orderID; private DateTime _orderDate;
        private DateTime _orderDate; private XMLProduct _product;
        private XMLProduct _product; private int _quantity;
        private int _quantity;
 Constructors
        Constructors
 Properties
        Properties
 public override string ToString()
        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}",
            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);
                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"?>
<?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">
<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>
    <OrderID>b695fd18-9cd7-4792-968a-0c0c3a3962c2</OrderID> <OrderDate>2007-03-09T00:00:00+08:00</OrderDate>
    <OrderDate>2007-03-09T00:00:00+08:00</OrderDate> <Product>
    <Product> <ProductID>23a2fe03-d0a0-4ce5-b213-c7e5196af566</ProductID>
        <ProductID>23a2fe03-d0a0-4ce5-b213-c7e5196af566</ProductID> <ProductName>Dell PC</ProductName>
        <ProductName>Dell PC</ProductName> <UnitPrice>4500</UnitPrice>
        <UnitPrice>4500</UnitPrice> </Product>
    </Product> <Quantity>300</Quantity>
    <Quantity>300</Quantity> </XMLOrder>
</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; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text; using System.Xml.Serialization;
using System.Xml.Serialization;
 namespace Artech.WCFSerialization
namespace Artech.WCFSerialization {
{ public class XMLProduct
    public class XMLProduct {
    { Private Fields
        Private Fields
 Constructors
        Constructors
 Properties
        Properties
 }
    } }
}
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text; using System.Xml.Serialization;
using System.Xml.Serialization;
 namespace Artech.WCFSerialization
namespace Artech.WCFSerialization {
{ [XmlRoot(Namespace = "http://artech.wcfSerialization/Samples/Order")]
    [XmlRoot(Namespace = "http://artech.wcfSerialization/Samples/Order")] public class XMLOrder
    public class XMLOrder {
    { private Guid _orderID;
        private Guid _orderID; private DateTime _orderDate;
        private DateTime _orderDate; private XMLProduct _product;
        private XMLProduct _product; private int _quantity;
        private int _quantity;
 Constructors
        Constructors
 Properties
        Properties
 public override string ToString()
        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}",
            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);
                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"?>
<?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">
<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">
  <product id="4e3aabe5-3a51-4000-9fd8-d821d164572a" xmlns="Http://Artech.WCFSerialization/Samples/Product"> <name>Dell PC</name>
    <name>Dell PC</name> <producingArea>Xiamen FuJian</producingArea>
    <producingArea>Xiamen FuJian</producingArea> <price>4500</price>
    <price>4500</price> </product>
  </product> <quantity>300</quantity>
  <quantity>300</quantity> <date>2007-03-09T00:00:00+08:00</date>
  <date>2007-03-09T00:00:00+08:00</date> </XMLOrder>
</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 | 调用默认构造函数 | 不会调用 | 
出处:http://artech.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
                    
                

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号