使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档。 此类不能被继承。
System.Runtime.Serialization.XmlObjectSerializer
System.Runtime.Serialization.DataContractSerializer
命名空间: System.Runtime.Serialization
程序集: System.Runtime.Serialization(在 System.Runtime.Serialization.dll 中)
使用 DataContractSerializer 类可以将类型实例序列化和反序列化为 XML 流或文档。 例如,可以使用包含重要数据(如名称和地址)的属性创建一个名为 Person 的类型。 然后,可以创建和操作一个 Person 类实例,并在 XML 文档中写入所有其属性值以便于以后检索,或者在 XML 流中写入这些值以立即进行传输。 最重要的是,DataContractSerializer 用于序列化和反序列化在 Windows Communication Foundation (WCF) 消息中发送的数据。 通过将 DataContractAttribute 特性应用于类,而将 DataMemberAttribute 特性应用于类成员,可以指定要序列化的属性和字段。
要使用 DataContractSerializer,请先创建一个类实例和适于写入或读取格式的对象;例如 XmlDictionaryWriter 实例。 然后调用 WriteObject 方法以保留数据。 要检索数据,请创建一个适于读取数据格式的对象(如 XML 文档的 XmlDictionaryReader),然后调用 ReadObject 方法。
您可以使用客户端应用程序配置文件中的 <dataContractSerializer> 元素来设置数据协定序列化程序的类型。
准备序列化或反序列化类
DataContractSerializer 与 DataContractAttribute 和 DataMemberAttribute 类结合使用。 要准备序列化某个类,请将 DataContractAttribute 应用于该类。对于返回要序列化的数据的类的每个成员,请应用 DataMemberAttribute。 您可以序列化字段和属性,而无论其可访问性级别是什么:private、protected、internal、protected internal 或 public。
例如,您的架构指定具有 ID 属性的 Customer,但现有类型名为 Person 且具有 Name 属性的应用程序。 要创建一个符合协定的类型,请先将 DataContractAttribute 应用于该类。然后,将 DataMemberAttribute 应用于每个要序列化的字段或属性。
说明 |
---|
可以将 DataMemberAttribute 同时应用于私有和公共成员。 |
XML 的最终格式不需要为文本。 相反,DataContractSerializer 以 XML infoset 形式写入数据,这样,即可以通过 XmlReader 和 XmlWriter 可将数据写入识别的任意格式。建议您使用 XmlDictionaryReader 和 XmlDictionaryWriter 类读取和写入数据,因为这两个类都经过优化可与 DataContractSerializer 一起使用。
如果要创建一个类,并且必须在进行序列化或反序列化之前填充其中的字段或属性 (Property),请使用回调属性 (Attribute),如版本容错序列化回调中所述。
添加到已知类型的集合中
在序列化或反序列化对象时,DataContractSerializer 必须“已知”该类型。 首先,创建一个实现 IEnumerable<T>(如 List<T>)的类实例,并将已知类型添加到集合中。 然后,使用接受 IEnumerable<T>(例如,[M:System.Runtime.Serialization.DataContractSerializer.#ctor(System.Type,System.Collections.Generic.IEnumerable{System.Type}])的重载之一创建DataContractSerializer 的实例。
说明 |
---|
与其他基元类型不同,默认情况下,DateTimeOffset 结构不是已知类型,因此,必须将其手动添加到已知类型列表中。 |
向前兼容性
DataContractSerializer 理解旨在与将来版本保持兼容的数据协定。 这些类型实现了 IExtensibleDataObject 接口。 此接口具有 ExtensionData 属性,该属性返回ExtensionDataObject 对象。
在部分信任模式下运行
在反序列化期间实例化目标对象时,DataContractSerializer 不调用目标对象的构造函数。 如果编写的 [DataContract] 类型可在部分信任模式下进行访问(即,它是公共类型并位于应用了 AllowPartiallyTrustedCallers 属性的程序集中),并且执行一些与安全有关的操作,则必须注意不要调用构造函数。 特别是,下面的方法无效:
-
如果尝试通过将构造函数指定为内部或私有或者将 LinkDemand 添加到构造函数中来限制部分信任访问;在部分信任模式下进行反序列化期间,这两种方法都没有任何效果。
-
如果编码的类假定构造函数已运行,该类可能会进入一种可被利用的无效内部状态。
下面的示例代码演示一种名为 Person 且由 DataContractSerializer 序列化的类型。 它将 DataContractAttribute 特性应用于类并将 DataMemberAttribute 应用于成员,以便向 DataContractSerializer 指示要序列化的内容。
namespace DataContractSerializerExample { using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; using System.Xml; // You must apply a DataContractAttribute or SerializableAttribute // to a class to have it serialized by the DataContractSerializer. [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")] class Person : IExtensibleDataObject { [DataMember()] public string FirstName; [DataMember] public string LastName; [DataMember()] public int ID; public Person(string newfName, string newLName, int newID) { FirstName = newfName; LastName = newLName; ID = newID; } private ExtensionDataObject extensionData_Value; public ExtensionDataObject ExtensionData { get { return extensionData_Value; } set { extensionData_Value = value; } } } public sealed class Test { private Test() { } public static void Main() { try { WriteObject("DataContractSerializerExample.xml"); ReadObject("DataContractSerializerExample.xml"); } catch (SerializationException serExc) { Console.WriteLine("Serialization Failed"); Console.WriteLine(serExc.Message); } catch (Exception exc) { Console.WriteLine( "The serialization operation failed: {0} StackTrace: {1}", exc.Message, exc.StackTrace); } finally { Console.WriteLine("Press <Enter> to exit...."); Console.ReadLine(); } } public static void WriteObject(string fileName) { Console.WriteLine( "Creating a Person object and serializing it."); Person p1 = new Person("Zighetti", "Barbara", 101); FileStream writer = new FileStream(fileName, FileMode.Create); DataContractSerializer ser = new DataContractSerializer(typeof(Person)); ser.WriteObject(writer, p1); writer.Close(); } public static void ReadObject(string fileName) { Console.WriteLine("Deserializing an instance of the object."); FileStream fs = new FileStream(fileName, FileMode.Open); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); DataContractSerializer ser = new DataContractSerializer(typeof(Person)); // Deserialize the data and read it from the instance. Person deserializedPerson = (Person)ser.ReadObject(reader, true); reader.Close(); fs.Close(); Console.WriteLine(String.Format("{0} {1}, ID: {2}", deserializedPerson.FirstName, deserializedPerson.LastName, deserializedPerson.ID)); } }