System.Runtime.Serialization.DataContractSerializer 类

本文提供了此 API 参考文档的补充说明。

使用 DataContractSerializer 类可以将类型实例序列化和反序列化为 XML 流或文档。 例如,可以使用包含重要数据(如名称和地址)的属性创建一个名为 Person 的类型。 然后,可以创建和操作一个 Person 类实例,并在 XML 文档中写入所有其属性值以便于以后检索,或者在 XML 流中写入这些值以立即进行传输。 最重要的是, DataContractSerializer 它用于序列化和反序列化在 Windows Communication Foundation (WCF) 消息中发送的数据。 通过将 DataContractAttribute 属性 (Attribute) 应用于类,而将 DataMemberAttribute 属性 (Attribute) 应用于类成员,可以指定要序列化的属性 (Property) 和字段。

有关可序列化的类型列表,请参阅 数据协定序列化程序支持的类型。

要使用 DataContractSerializer,请先创建一个类实例和适于写入或读取格式的对象;例如 XmlDictionaryWriter 实例。 然后调用 WriteObject 方法以保留数据。 要检索数据,请创建一个适于读取数据格式的对象(如 XML 文档的 XmlDictionaryReader),然后调用 ReadObject 方法。

有关使用 DataContractSerializer的详细信息,请参阅 序列化和反序列化

可以使用客户端应用程序配置文件中的 dataContractSerializer> 元素设置数据协定序列化程序<的类型。

准备用于序列化或反序列化的类

DataContractSerializerDataContractAttributeDataMemberAttribute 类结合使用。 要准备序列化某个类,请将 DataContractAttribute 应用于该类。 对于返回要序列化的数据的类的每个成员,请应用 DataMemberAttribute。 您可以序列化字段和属性,而无论其可访问性级别是什么:private、protected、internal、protected internal 或 public。

例如,您的架构指定具有 Customer 属性的 ID,但现有应用程序已使用一个名为 Person 且具有 Name 属性的类型。 要创建一个符合协定的类型,请先将 DataContractAttribute 应用于该类。 然后,将 DataMemberAttribute 应用于每个要序列化的字段或属性。

注意

可以将 DataMemberAttribute 同时应用于私有和公共成员。

XML 的最终格式不需要为文本。 相反,DataContractSerializer 以 XML infoset 形式写入数据,这样,即可以 XmlReaderXmlWriter 可识别的任意格式写入数据。 建议您使用 XmlDictionaryReaderXmlDictionaryWriter 类读取和写入数据,因为这两个类都经过优化可与 DataContractSerializer 一起使用。

如果要创建一个在序列化或反序列化发生前必须填充的字段或属性的类,请使用回调属性,如版本容错序列化回调中所述

添加到已知类型的集合

在序列化或反序列化对象时,DataContractSerializer 必须“已知”该类型。 首先,创建一个实现 IEnumerable<T>(如 List<T>)的类实例,并将已知类型添加到集合中。 然后,使用采用 (例如, DataContractSerializer(Type, IEnumerable<Type>)) 的重载IEnumerable<T>之一创建实例DataContractSerializer

注意

与其他基元类型不同, DateTimeOffset 结构默认不是已知类型,因此必须手动将其添加到已知类型列表中(请参阅 数据协定已知类型)。

向前兼容性

DataContractSerializer 理解旨在与将来版本保持兼容的数据协定。 这些类型实现了 IExtensibleDataObject 接口。 此接口具有 ExtensionData 属性,该属性返回 ExtensionDataObject 对象。 有关详细信息,请参阅向前兼容的数据协定

在部分信任下运行

在反序列化期间实例化目标对象时,DataContractSerializer 不调用目标对象的构造函数。 如果创作 可从部分信任访问的 [DataContract] 类型(也就是说,它是公共的,并且是在应用 AllowPartiallyTrustedCallers 了属性的程序集中),并且执行某些与安全相关的操作,则必须注意构造函数未调用。 特别是,下面的方法无效:

  • 如果尝试通过将构造函数指定为内部或私有或者将 LinkDemand 添加到构造函数中来限制部分信任访问;在部分信任模式下进行反序列化期间,这两种方法都没有任何效果。
  • 如果编码的类假定构造函数已运行,该类可能会进入一种可被利用的无效内部状态。