指定该类型要定义或实现一个数据协定,并可由序列化程序(如 DataContractSerializer)进行序列化。 若要使其类型可序列化,类型作者必须为其类型定义数据协定。
程序集: System.Runtime.Serialization(在 System.Runtime.Serialization.dll 中)
DataContractAttribute 类型公开以下成员。
名称 | 说明 | |
---|---|---|
![]() ![]() ![]() | DataContractAttribute | 初始化 DataContractAttribute 类的新实例。 |
将 DataContractAttribute 属性应用于由 DataContractSerializer 执行的序列化和反序列化操作中所使用的类型(类、结构或枚举)。 如果您通过使用 Windows Communication Foundation (WCF) 基础结构发送或接收消息,还应将 DataContractAttribute 应用于任何保存和操作这些消息中发送的数据的类。 有关以下内容的更多信息数据协定的更多信息,请参见Using Data Contracts。
此外,还必须将 DataMemberAttribute 应用于任何保存您要序列化的值的字段、属性或事件。 通过应用 DataContractAttribute,可以显式启用 DataContractSerializer 来序列化和反序列化数据。
![]() |
---|
可将 DataMemberAttribute 应用于私有字段。 请注意,字段(即使是私有字段)所返回的数据将被序列化和反序列化,因此恶意用户或进程可以查看或截获这些数据。 |
有关以下内容的更多信息数据协定的更多信息,请参见Using Data Contracts中列出的主题。
数据协定
“数据协定”是一组字段的抽象说明,并且包含每个字段的名称和数据类型。 数据协定存在于任何单个实现的外部,以使不同平台上的服务可以交互操作。 只要在服务之间传递的数据符合同一协定,这些数据就可以由所有服务进行处理。 这一处理也称为“松耦合系统”。 此外,数据协定还与接口类似,因为它指定了为使数据可由应用程序进行处理而必须使用的传送方式。 例如,数据协定可以定义一个名为“Person”的数据类型,它有两个文本字段,分别名为“FirstName”和“LastName”。 若要创建数据协定,请将 DataContractAttribute 应用于类并将 DataMemberAttribute 应用于所有必须序列化的字段或属性。 序列化后,数据将符合隐式内置到类型中的数据协定。
![]() |
---|
在其继承行为方面,数据协定明显不同于实际接口。 接口由任何派生类型继承。 在将 DataContractAttribute 应用于基类时,派生类型不会继承属性或行为。 但是,如果派生类型具有数据协定,则基类的数据成员将被序列化。 不过,若要使派生类中的新成员可序列化,必须向这些成员应用 DataMemberAttribute。 |
XML 架构文档和 SvcUtil 工具
如果要与其他服务交换数据,则必须描述数据协定。 对于 DataContractSerializer 的当前版本,可使用 XML 架构来定义数据协定。 (也可以使用其他形式的元数据/说明来实现此目的。) 创建从应用程序的 XML 架构,请使用 /dconly 命令行选项的 Service Model Metadata Utility Tool (Svcutil.exe) 。 如果该工具的输入为程序集,则默认情况下该工具会生成一组 XML 架构,这些架构定义了该程序集中包含的所有数据协定类型。 反过来,还可使用 Svcutil.exe 工具创建符合以下 XML 架构的要求的 Visual Basic 或 C# 类定义:XML 架构使用可由数据协定表示的构造。 在此示例中,不需要 /dconly 命令行选项。
如果 Svcutil.exe 工具的输入为 XML 架构,则默认情况下该工具会创建一组类。 如果对这些类进行检查,您会发现 DataContractAttribute 已经应用。 可以使用这些类创建一个新的应用程序,用来处理必须与其他服务交换的数据。
此外,您还可以对返回 Web Services 描述语言 (WSDL) 文档的终结点运行该工具,以自动生成用于创建 Windows Communication Foundation (WCF) 客户端的代码和配置。 所生成的代码包含带有 DataContractAttribute 标记的类型。
重用现有类型
数据协定具有两个基本要求:一个稳定的名称和一个成员列表。 该稳定名称由该协定的命名空间统一资源标识符 (URI) 和本地名称组成。 默认情况下,在将 DataContractAttribute 应用于类时,它会将类名称用作本地名称,而将类的命名空间(以“http://schemas.datacontract.org/2004/07/”为前缀)作为命名空间 URI。 可通过设置 Name 和 Namespace 属性来重写这些默认值。 此外,还可通过将 ContractNamespaceAttribute 应用于命名空间来更改命名空间。 当现有类型能够完全根据您的需要处理数据,但其命名空间和类名与数据协定不同时,请使用此功能。 通过重写默认值,可以重用现有类型并使序列化数据符合数据协定。
![]() |
---|
在任意代码中,都可以用 DataContract 一词来代替较长的 DataContractAttribute。 |
版本控制
数据协定还可以与其自身的后续版本兼容。 也就是说,当协定的后续版本包含额外数据时,已存储并返回给发送方的数据将保持不变。 为此,应实现 IExtensibleDataObject 接口。
有关以下内容的更多信息版本管理的更多信息,请参见Data Contract Versioning。
下面的示例序列化和反序列化了一个名为 Person 的类,该类已应用 DataContractAttribute。 请注意,Namespace 和 Name 属性已设置为对默认设置进行重写的值。
namespace DataContractAttributeExample { // Set the Name and Namespace properties to new values. [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")] class Person : IExtensibleDataObject { // To implement the IExtensibleDataObject interface, you must also // implement the ExtensionData property. private ExtensionDataObject extensionDataObjectValue; public ExtensionDataObject ExtensionData { get { return extensionDataObjectValue; } set { extensionDataObjectValue = value; } } [DataMember(Name = "CustName")] internal string Name; [DataMember(Name = "CustID")] internal int ID; public Person(string newName, int newID) { Name = newName; ID = newID; } } class Test { public static void Main() { try { WriteObject("DataContractExample.xml"); ReadObject("DataContractExample.xml"); Console.WriteLine("Press Enter to end"); Console.ReadLine(); } catch (SerializationException se) { Console.WriteLine ("The serialization operation failed. Reason: {0}", se.Message); Console.WriteLine(se.Data); Console.ReadLine(); } } public static void WriteObject(string path) { // Create a new instance of the Person class and // serialize it to an XML file. Person p1 = new Person("Mary", 1); // Create a new instance of a StreamWriter // to read and write the data. FileStream fs = new FileStream(path, FileMode.Create); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs); DataContractSerializer ser = new DataContractSerializer(typeof(Person)); ser.WriteObject(writer, p1); Console.WriteLine("Finished writing object."); writer.Close(); fs.Close(); } public static void ReadObject(string path) { // Deserialize an instance of the Person class // from an XML file. First create an instance of the // XmlDictionaryReader. FileStream fs = new FileStream(path, FileMode.OpenOrCreate); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); // Create the DataContractSerializer instance. DataContractSerializer ser = new DataContractSerializer(typeof(Person)); // Deserialize the data and read it from the instance. Person newPerson = (Person)ser.ReadObject(reader); Console.WriteLine("Reading this object:"); Console.WriteLine(String.Format("{0}, ID: {1}", newPerson.Name, newPerson.ID)); fs.Close(); } } }
.NET Framework
受以下版本支持:4.5、4、3.5、3.0.NET Framework Client Profile
受以下版本支持:4、3.5 SP1可移植类库
受以下版本支持:可移植类库适用于 Windows 应用商店应用的 .NET
受以下版本支持:Windows 8Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008(不支持服务器核心角色), Windows Server 2008 R2(支持带 SP1 或更高版本的服务器核心角色;不支持 Itanium)
.NET Framework 并不是对每个平台的所有版本都提供支持。有关支持的版本的列表,请参见.NET Framework 系统要求。