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

    xiaoxiao2021-03-25  51

    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

    调用默认构造函数

    不会调用

    暖阳下的好日子 认证博客专家 神经网络 数据分析 Python 11年的程序经验,擅长应用系统,人工智能。拥有丰富的系统开发经验,数据库操作经验。除此之外,还喜欢足球,魔兽。
    转载请注明原文地址: https://ju.6miu.com/read-150019.html

    最新回复(0)