博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的WCF之旅(4):WCF中的序列化[下篇]
阅读量:6973 次
发布时间:2019-06-27

本文共 4603 字,大约阅读时间需要 15 分钟。

... ...续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
ExpandedBlockStart.gif {
    
public 
class XMLProduct
ExpandedSubBlockStart.gif    {
ContractedSubBlock.gif        
Private Fields
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Artech.WCFSerialization
ExpandedBlockStart.gif {
    
public 
class XMLOrder
ExpandedSubBlockStart.gif    {
        
private Guid _orderID;
        
private DateTime _orderDate;
        
private XMLProduct _product;
        
private 
int _quantity;
ContractedSubBlock.gif        
Constructors
ContractedSubBlock.gif        
Properties
        
public 
override 
string ToString()
ExpandedSubBlockStart.gif        {
            
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.

ContractedBlock.gif

调用上面定义的方法,生成序列化的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
ExpandedBlockStart.gif {
    
public 
class XMLProduct
ExpandedSubBlockStart.gif    {
ContractedSubBlock.gif        
Private Fields
ContractedSubBlock.gif        
Constructors
ContractedSubBlock.gif        
Properties
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
namespace Artech.WCFSerialization
ExpandedBlockStart.gif {
    [XmlRoot(Namespace = "http://artech.wcfSerialization/Samples/Order")]
    
public 
class XMLOrder
ExpandedSubBlockStart.gif    {
        
private Guid _orderID;
        
private DateTime _orderDate;
        
private XMLProduct _product;
        
private 
int _quantity;
ContractedSubBlock.gif        
Constructors
ContractedSubBlock.gif        
Properties
        
public 
override 
string ToString()
ExpandedSubBlockStart.gif        {
            
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。

ContractedBlock.gif

调用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相关内容:
作者:蒋金楠
微信公众账号:大内老A
微博:
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号
蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
你可能感兴趣的文章
a前缀
查看>>
LeetCode第七天
查看>>
java中json的使用和解析
查看>>
C语言面试笔试整理笔记(二)
查看>>
Hibernate 5.x 配置 C3P0 数据库连接池
查看>>
自测是保证开发提交代码质量的最基本方法和最低要求
查看>>
Java_myeclipse添加DTD约束(框架xml只能提示功能)
查看>>
CSS3基础知识学习
查看>>
eclipse 创建普通maven项目
查看>>
vue webpack build 打包过滤console.log()日志
查看>>
iOS — Autolayout之Masonry解读
查看>>
ORACLE存储过程 练习系列三 失效或者生效指定表的外键
查看>>
用户表空间查询
查看>>
求整数数组中最大子数组的和
查看>>
hdu2546-饭卡???
查看>>
Silverlight 获取控件间的相对位置
查看>>
vscode icon in elementary os
查看>>
Android环境搭建(Windows)
查看>>
MSHFLEXGRID控件常用属性
查看>>
去除iframe滚动条
查看>>