前言
本次课程的主要内容包括以下四格部分:DataContractSerializer、序列化、反序列化、XmlSerializer
第一部分--DataContractSerializer
Windows Communication Foundation(WCF)包括新序列化引擎DataContractSerializer。DataContractSerializer可在.NET Framework对象和XML之间进行双向转换。
在对.NET Framework 对象进行序列化时,序列化程序了解各种序列化编程模型,包括新的数据协定模型。
当对XML进行反序列化时,序列化程序使用XmlReader和XmlWriter类。在某些情况下(例如在使用WCF二进制XML格式时),序列化程序也支持XmlDictionaryReader和XmlDictionaryWriter类以使其能够生成优化的XML。
WCF还包括一个伴随序列化程序NetDataContractSerializer。NetDataContractSerializer与BinaryFormatter和SoapFormatter序列化程序类似,因为它也发出.NET Framework类型名称作为序列化数据的一部分。当在序列化和反序列化结束阶段共享相同的类型时使用此序列化程序。
DataContractSerializer和NetDataContractSerializer都派生自公共基类XmlObjectSerializer。
创建DataContractSerializer实例
1.指定根类型
根类型是序列化或反序列化实例的类型。DtaContractSerializer有许多构造函数重载,但必须使用type参数听歌至少一个根类型
为某个根类型创建的序列化程序不能用于序列化(或反序列化)其他类型,除非该类型是从根类型派生的。
2.指定已知类型
如果在进行序列化的类型中涉及多态性并且尚未使用KnowTypeAttribute属性或一些其他机制进行处理,则必须使用KnownTypes参数将可能的已知类型的列表传递给序列化程序的构造函数
3.指定默认根名称和命名空间
通常,在对对象进行序列化时,将根据数据协定名称和命名空间确定最外面的XML元素的默认名称和命名空间。所有内部元素的名称将根据数据成员名称来确定,这些元素的命名空间是数据协定的命名空间
4.设置最大对象配额
一些DataContractSerializer构造函数重载具有maxitemsInObjectGraph参数。此参数确定序列化程序在单个ReadObject方法调用中序列化或反序列化的对象最大数目。(该方法总是读取一个跟对象,但此对象的数据成员可以具有其他对象。这些对象又可以具有其他对象,依次类推。)默认值为65536.
注意,当序列化或反序列化数组时,每个数组项都计为一个单独的对象
5.往返行程
在一次操作中对对象进行反序列化和重新序列化时将发生往返行程。因此,往返行程是从XML到对象实例,然后再返回到XML流。
一些DataContractSerializer构造函数重载具有ignoreExtensionDataOjbect参数,该参数默认设置为false。
在此默认模式中,对于一个往返行程,可以将数据从数据协定的较新版本发送到较旧版本然后再返回到较新版本而不会出现任何损失,前提是数据协定实现IExtensibleDataObject接口。例如,假设Person数据协定的版本1包含Name和PhoneNumber数据成员,并且版本2添加Nickname成员。如果在从版本2发送信息到版本1时实现IextensibleDataObject,则存储Nickname数据,并在再次反序列化数据时再次发出这些数据,因此在往返行程中不会出现数据丢失。
启用和禁用往返行程
要关闭往返行程,请不要实现IExtensibleDataObjcet接口。如果您无法控制相应的类型,则将ignoreExtensionDataOjbect参数设置为true也可获得同样的效果。
对象图保留此方法具有以下可能不需要的特征:
性能。复制数据的效率低。
循环引用。如果对象引用自身,甚至通过其他对象引用自身,则通过复制进行序列化会导致无限循环。(如果发生这种状况,序列化程序将引发SerializationException.)
语义。有时,一定要记住这一点:两个引用指向的是同一个对象而不是两个相同的对象
有关这些原因,一些DataContractSerializer构造函数重载具有preserveObjectReferences参数(默认值为false)。在将此参数设置为true时,将使用只有WCF才可以理解的编码引用的特殊方法。
“ser”命名空间引用标准序列化命名空间。每一段数据只进行一次序列化并获得一个ID号,后续使用会导致引用已序列化的数据。
此模式的限制
DataContractSerializer在preserveObjectReferences设置为true的情况下生成的XML与任何其他技术都无法进行交互,仅可以由另一个其preserverObjectReferences也设置为true的DataContractSerializer实例进行访问。
元数据(架构)不支持此功能。生成的架构仅对preserveObjectReferences设置为false的情况有效。
此功能可能导致序列化和反序列化进程运行速度减慢。尽管不必复制数据,但是在此模式中必须执行额外的对象比较。
关于DataContractSerializer的小实例请点击下载代码示例
第二部分--序列化
简单序列化
对对象进行序列化最基本的方法是将其传递到WriteObject方法。
该方法有三个重载,每个重载分别用于写入到Stream、XmlWriter或XmlDictionaryWriter.
使用Stream重载时,输出是采用UTF-8编码的XML。
使用XmlDictionaryWriter重载时,序列化程序会针对二进制XML优化其输出。
分布引导的序列化
WriteStartObject、WriteObjectContent和WriteEnObject方法可分别用于写入结束元素、写入对象内容以及关闭包装元素
此分步引导的序列化具有两个常见用途。一种用途是在WriteStartObject和WriteObjectContent之间插入内容(例如属性或注释)
另一种常见用途是完全避免使用WritStartObject和WriteEndObject,并写入自己的自定义包装元素(或者甚至连同跳过写入包装)
第三部分--反序列化
对对象进行反序列化的最基本的方式是调用ReadObject方法重载之一。
该方法有三个重载,每个重载分别用于读取XmlDictionaryReader、XmlReader或Stream。请注意,Stream重载将创建不受任何配额保护的文本XmlDictionaryReader,此重载仅应用于读取受信任的数据。
还请注意,必须ReadObject方法返回的对象强制转换为适当的类型
第四部分--XmlSerializer
WCF还支持XmlSerializer,XmlSerializer类并非专用于WCF,ASP.NET Web服务同样也使用该序列化引擎。
XmlSerializer类支持的类型少于DataContractSerializer类支持的类型,但它允许对生成的XMl进行更多的控制,并且支持更多的XML架构定义语言(XSD)标准。
它也不需要在可序列化类型上有任何声明性属性。XMLSerializer类并不支持数据协定类型。
手动切换到XmlSerializer
将应用程序从ASP.NET Web 服务迁移到WCF时,您可能需要重写现有的、与XmlSerializer兼容的类型,而不是创建新的数据协定类型。
当对出现在消息中的XML的精确控制很重要,而Web服务描述语言(WSDL)文档不可用时,例如,在使用必须遵循某个已标准化且已发布的架构(与DataContractSerializer不兼容)的类型来创建服务时。
创建遵循旧式SOAP编码标准的服务时。
在序列化数据协定类型时,DataContractSerializer类只序列化用DataMemberAttribute属性标记的成员。
如果在选择了XmlSerializer类的服务协定中不慎使用了该类型,则将序列化creitCardNumber成员,这可能并不是想要的结果
关于XmlSerializer序列化实例,有服务,有客户端调用代码示例
总结
DataContractSerializer支持的类型
-数据协定类型。这些是已应用了DataContractAttribute属性的类型。表示业务对象的新自定义类型通常应作为数据协定类型创建。有关更多信息,请参见使用数据协定。
集合类型。这些是表示数据列表的类型。这些类型可以是常规的类型数组或集合类型,例如,ArrayList和Dictionary.CollectionDataContractAttribute属性可以用于自定义这些类型的序列化,但不是必需的。
枚举类型。枚举(包括标志枚举)是可序列化的。或者可以使用DataContractAttribute属性对枚举类型进行标记,在这种情况下,必须使用EnumMemberAttribute属性对每个成员进行标记。
.NET Framework基元类型。集成到.NET Framework中的下列类型都可以进行序列化,并可视为基元类型:byte、SByte、Int16、Int32、Int64、UInt16、UInt32、UInt64、Single、Single、Double、Boolean、Char、Decimal、Object和String.
其他基元类型。这些类型不是.NET Framework中的基元,但可作为采用序列化的XML形式的基元。这些类型有DateTime、DateTimeOffset、TieSpan、Guid、Uri、XmlQualifiedName和Byte数
使用SerializableAttribute属性标记的类型。.NET Framework基类库中包含的许多类型都属于此类别。DataContractSerializer完全支持由.NET Framework远程处理、BinaryFormatter和SoapFormatter使用的此序列化编程模型,包括支持Iserializable接口。
表示原始XML的类型或表示ADO.NET关系数据的类型。支持XmlElement和XmlNode类型的数组作为一种直接表示XML的方式。另外,支持实现IXmlSerializable接口的类型,包括相关的XmlSchemaProviderAttribute属性、XDocument和XElement类型。
ADO.NET DataTable类型和DataSet类型(以及其类型化的派生类)都实现IXmlSerializable接口,因此可归入此类别。