本文提供了此 API 参考文档的补充说明。
使用 DataContractSerializer 类将类型的实例序列化和反序列化为 XML 流或文档。 例如,可以创建一个包含基本数据(例如名称和地址)的属性命名 Person
的类型。 然后,可以创建和处理 Person
类的实例,并将其所有属性值写入 XML 文档,以便以后检索,或者在 XML 流中直接传输。 最重要的是, DataContractSerializer 它用于序列化和反序列化在 Windows Communication Foundation (WCF) 消息中发送的数据。 将 DataContractAttribute 属性应用于类,并将 DataMemberAttribute 属性应用于类成员,以指定序列化的属性和字段。
有关可序列化的类型列表,请参阅 数据协定序列化程序支持的类型。
要使用 DataContractSerializer,请先创建一个类的实例和一个适合写入或读取格式的对象;例如,类的 XmlDictionaryWriter实例。 然后调用 WriteObject 该方法来保存数据。 若要检索数据,请创建一个适合读取数据格式的对象(如 XmlDictionaryReader XML 文档的对象),并调用 ReadObject 该方法。
有关使用 DataContractSerializer的详细信息,请参阅 序列化和反序列化。
可以使用客户端应用程序配置文件中的 dataContractSerializer< 元素设置数据协定序列化程序>的类型。
准备序列化或反序列化类
DataContractSerializer 与 DataContractAttribute 和 DataMemberAttribute 类配合使用。 要准备序列化某个类,请将 DataContractAttribute 应用于该类。 对于返回要序列化的数据的类的每个成员,请应用 DataMemberAttribute。 您可以序列化字段和属性,而无论其可访问性级别是什么:private、protected、internal、protected internal 或 public。
例如,您的架构指定Customer
类型带有ID
属性,但已有一个现有应用程序使用Person
类型并具有Name
属性。 若要创建符合协定的类型,请先在该类上应用 DataContractAttribute。 然后,将 DataMemberAttribute 应用于要序列化的每个字段或属性。
注释
可以将 DataMemberAttribute 应用于私有成员和公共成员。
XML 的最终格式不是文本。 相反,DataContractSerializer 将数据写入为 XML 信息集,这使你能够将数据写入由 XmlReader 和 XmlWriter 识别的任何格式。 建议使用 XmlDictionaryReader 和 XmlDictionaryWriter 类来读取和写入,因为两者都经过优化以使用 DataContractSerializer。
如果要创建一个在序列化或反序列化发生前必须填充的字段或属性的类,请使用回调属性,如 Version-Tolerant 序列化回调中所述。
添加到已知类型的集合中
在序列化或反序列化对象时,DataContractSerializer 必须“已知”该类型。 首先创建实现 IEnumerable<T> (例如 List<T>)的类的实例,并将已知类型添加到集合。 然后,使用接受 DataContractSerializer(例如,IEnumerable<T>)的重载之一创建 DataContractSerializer(Type, IEnumerable<Type>) 的实例。
注释
与其他基元类型不同, DateTimeOffset 结构默认不是已知类型,因此必须手动将其添加到已知类型列表中(请参阅 数据协定已知类型)。
向前兼容性
DataContractSerializer 理解旨在与将来版本保持兼容的数据协定。 此类类型实现 IExtensibleDataObject 接口。 该接口具有 ExtensionData 属性,此属性返回一个 ExtensionDataObject 对象。 有关详细信息,请参阅 Forward-Compatible 数据协定。
在部分信任下运行
在反序列化期间实例化目标对象时, DataContractSerializer 不调用目标对象的构造函数。 如果创建一个可以从部分信任访问的 [DataContract] 类型(也就是说,它是公有的,并且位于应用了 AllowPartiallyTrustedCallers
属性的程序集中),并且执行某些与安全相关的操作,则必须注意构造函数未被调用。 具体而言,以下技术不起作用:
- 如果尝试通过使构造函数声明为 internal 或 private,或者向构造函数添加
LinkDemand
指令来限制部分信任访问,则这些措施在部分信任下进行反序列化时都没有效果。 - 如果您编写假设构造函数已运行的类,该类可能会进入一种可被利用的无效内部状态。