zoukankan      html  css  js  c++  java
  • WCF中的序列化[下篇]

    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
        
    {
            
    #region Private Fields
            
    private Guid _productID;
            
    private string _productName;
            
    private string _producingArea;
            
    private double _unitPrice;
           
            
    #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


            
    #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;
    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;

            
    #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


            
    #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.

    调用上面定义的方法,生成序列化的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关系:

    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。

    以上这些都是默认的Mapping关系,同DataContractSerializer一样,我们可以通过在Type以及它的成员中运用一些Attribute来改这种默认的Mapping。

    1. Root Element名称之后能为类名。
    2. 可以在Type上运用XMLRoot,通过Namaspace参数在Root Element指定Namespace。
    3. 可以通过在类成员上运用XMLElement Attribute和XMLAttribute Attribute指定对象成员转化成XMLElement还是XMLAttribute。并且可以通过NameSpace参数定义Namespace。
    4. 可以在XMLElement或者XMLAttribute Attribute 通过Order参数指定成员在XML出现的位置。
    5. 可以通过XmlIgnore attribute阻止对象成员被序列化。

    基于上面这些,我们重新定义了XMLProduct和XMLOrder。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Xml.Serialization;

    namespace Artech.WCFSerialization
    {
        
    public class XMLProduct
        
    {
            
    #region Private Fields
            
    private Guid _productID;
            
    private string _productName;
            
    private string _producingArea;
            
    private double _unitPrice;
            
    #endregion


            
    #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


            
    #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;

            
    #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


            
    #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。

    调用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 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
     

  • 相关阅读:
    计算函数执行时间
    Go语言生成随机数
    413 Request Entity Too Large
    JavaScript变量与数据类型详解
    OAuth2.0认证详解
    prompt的工作原理
    JS 实现上传图片
    移动端的长按事件的实现
    实现自动关闭当前页面的效果
    前端异常捕获与上报
  • 原文地址:https://www.cnblogs.com/guanjie20/p/2203991.html
Copyright © 2011-2022 走看看