DataContractAttribute 类

定义

指定该类型要定义或实现一个数据协定,并可由序列化程序(如 DataContractSerializer)进行序列化。Specifies that the type defines or implements a data contract and is serializable by a serializer, such as the DataContractSerializer. 若要使其类型可序列化,类型作者必须为其类型定义数据协定。To make their type serializable, type authors must define a data contract for their type.

public ref class DataContractAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Enum | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=false)]
public sealed class DataContractAttribute : Attribute
type DataContractAttribute = class
    inherit Attribute
Public NotInheritable Class DataContractAttribute
Inherits Attribute
继承
DataContractAttribute
属性

示例

下面的示例序列化和反序列化了一个名为 Person 的类,该类已应用 DataContractAttributeThe following example serializes and deserializes a class named Person to which the DataContractAttribute has been applied. 请注意,NamespaceName 属性已设置为对默认设置进行重写的值。Note that the Namespace and Name properties have been set to values that override the default settings.

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();
        }

    }
}
Namespace DataContractAttributeExample
    ' Set the Name and Namespace properties to new values.
    <DataContract(Name := "Customer", [Namespace] := "http://www.contoso.com")>  _
    Class Person
        Implements IExtensibleDataObject
        ' To implement the IExtensibleDataObject interface, you must also
        ' implement the ExtensionData property.
        Private extensionDataObjectValue As ExtensionDataObject 
        
        Public Property ExtensionData() As ExtensionDataObject _
          Implements IExtensibleDataObject.ExtensionData
            Get
                Return extensionDataObjectValue
            End Get
            Set
                extensionDataObjectValue = value
            End Set
        End Property
        
        <DataMember(Name := "CustName")>  _
        Friend Name As String
        
        <DataMember(Name := "CustID")>  _
        Friend ID As Integer
        
        
        Public Sub New(ByVal newName As String, ByVal newID As Integer) 
            Name = newName
            ID = newID
        
        End Sub 
    End Class 
    
    
    Class Test
        
        Public Shared Sub Main() 
            Try
                WriteObject("DataContractExample.xml")
                ReadObject("DataContractExample.xml")
                Console.WriteLine("Press Enter to end")
                Console.ReadLine()
            Catch se As SerializationException
                Console.WriteLine("The serialization operation failed. Reason: {0}", _
                   se.Message)
                Console.WriteLine(se.Data)
                Console.ReadLine()
            End Try
        
        End Sub 
        
        
        Public Shared Sub WriteObject(ByVal path As String) 
            ' Create a new instance of the Person class and 
            ' serialize it to an XML file.
            Dim p1 As New Person("Mary", 1)
            ' Create a new instance of a StreamWriter
            ' to read and write the data.
            Dim fs As New FileStream(path, FileMode.Create)
            Dim writer As XmlDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(fs)
            Dim ser As New DataContractSerializer(GetType(Person))
            ser.WriteObject(writer, p1)
            Console.WriteLine("Finished writing object.")
            writer.Close()
            fs.Close()
        
        End Sub 
        
        Public Shared Sub ReadObject(ByVal path As String) 
            ' Deserialize an instance of the Person class 
            ' from an XML file. First create an instance of the 
            ' XmlDictionaryReader.
            Dim fs As New FileStream(path, FileMode.OpenOrCreate)
            Dim reader As XmlDictionaryReader = XmlDictionaryReader. _
              CreateTextReader(fs, New XmlDictionaryReaderQuotas())
            
            ' Create the DataContractSerializer instance.
            Dim ser As New DataContractSerializer(GetType(Person))
            
            ' Deserialize the data and read it from the instance.
            Dim newPerson As Person = CType(ser.ReadObject(reader), Person)
            Console.WriteLine("Reading this object:")
            Console.WriteLine(String.Format("{0}, ID: {1}", newPerson.Name, newPerson.ID))
            fs.Close()
        
        End Sub 
    End Class 
End Namespace 

注解

DataContractAttribute 属性应用于由 DataContractSerializer 执行的序列化和反序列化操作中所使用的类型(类、结构或枚举)。Apply the DataContractAttribute attribute to types (classes, structures, or enumerations) that are used in serialization and deserialization operations by the DataContractSerializer. 如果使用 Windows Communication Foundation (WCF)基础结构发送或接收消息,还应将应用DataContractAttribute于任何保存和操作在消息中发送的数据的类。If you send or receive messages by using the Windows Communication Foundation (WCF) infrastructure, you should also apply the DataContractAttribute to any classes that hold and manipulate data sent in messages. 有关数据协定的详细信息,请参阅使用数据协定For more information about data contracts, see Using Data Contracts.

此外,还必须将 DataMemberAttribute 应用于任何保存您要序列化的值的字段、属性或事件。You must also apply the DataMemberAttribute to any field, property, or event that holds values you want to serialize. 通过应用 DataContractAttribute,可以显式启用 DataContractSerializer 来序列化和反序列化数据。By applying the DataContractAttribute, you explicitly enable the DataContractSerializer to serialize and deserialize the data.

注意

可将 DataMemberAttribute 应用于私有字段。You can apply the DataMemberAttribute to private fields. 请注意,字段(即使是私有字段)所返回的数据将被序列化和反序列化,因此恶意用户或进程可以查看或截获这些数据。Be aware that the data returned by the field (even if it is private) is serialized and deserialized, and thus can be viewed or intercepted by a malicious user or process.

有关数据协定的详细信息,请参阅使用数据协定中列出的主题。For more information about data contracts, see the topics listed in Using Data Contracts.

数据协定Data Contracts

数据协定是一组字段的抽象说明,其中每个字段都具有名称和数据类型。A data contract is an abstract description of a set of fields with a name and data type for each field. 数据协定存在于任何单个实现的外部,以使不同平台上的服务可以交互操作。The data contract exists outside of any single implementation to allow services on different platforms to interoperate. 只要在服务之间传递的数据符合同一协定,这些数据就可以由所有服务进行处理。As long as the data passed between the services conforms to the same contract, all the services can process the data. 此处理也称为松耦合系统This processing is also known as a loosely coupled system. 此外,数据协定还与接口类似,因为它指定了为使数据可由应用程序进行处理而必须使用的传送方式。A data contract is also similar to an interface in that the contract specifies how data must be delivered so that it can be processed by an application. 例如,数据协定可以定义一个名为“Person”的数据类型,它有两个文本字段,分别名为“FirstName”和“LastName”。For example, the data contract may call for a data type named "Person" that has two text fields, named "FirstName" and "LastName". 若要创建数据协定,请将 DataContractAttribute 应用于类并将 DataMemberAttribute 应用于所有必须序列化的字段或属性。To create a data contract, apply the DataContractAttribute to the class and apply the DataMemberAttribute to any fields or properties that must be serialized. 序列化后,数据将符合隐式内置到类型中的数据协定。When serialized, the data conforms to the data contract that is implicitly built into the type.

备注

在其继承行为方面,数据协定明显不同于实际接口。A data contract differs significantly from an actual interface in its inheritance behavior. 接口由任何派生类型继承。Interfaces are inherited by any derived types. 在将 DataContractAttribute 应用于基类时,派生类型不会继承属性或行为。When you apply the DataContractAttribute to a base class, the derived types do not inherit the attribute or the behavior. 但是,如果派生类型具有数据协定,则基类的数据成员将被序列化。However, if a derived type has a data contract, the data members of the base class are serialized. 不过,若要使派生类中的新成员可序列化,必须向这些成员应用 DataMemberAttributeHowever, you must apply the DataMemberAttribute to new members in a derived class to make them serializable.

XML 架构文档和 SvcUtil 工具XML Schema Documents and the SvcUtil Tool

如果要与其他服务交换数据,则必须描述数据协定。If you are exchanging data with other services, you must describe the data contract. 对于 DataContractSerializer 的当前版本,可使用 XML 架构来定义数据协定。For the current version of the DataContractSerializer, an XML schema can be used to define data contracts. (也可以使用其他形式的元数据/说明来实现此目的。)若要从你的应用程序创建 XML 架构,请将Svcutil.exe 元数据实用工具()/dconly命令行选项一起使用。(Other forms of metadata/description could be used for the same purpose.) To create an XML schema from your application, use the ServiceModel Metadata Utility Tool (Svcutil.exe) with the /dconly command line option. 如果该工具的输入为程序集,则默认情况下该工具会生成一组 XML 架构,这些架构定义了该程序集中包含的所有数据协定类型。When the input to the tool is an assembly, by default, the tool generates a set of XML schemas that define all the data contract types found in that assembly. 反过来,还可使用 Svcutil.exe 工具创建符合以下 XML 架构的需求的 Visual Basic 或 C# 类定义:XML 架构使用可由数据协定表示的构造。Conversely, you can also use the Svcutil.exe tool to create Visual Basic or C# class definitions that conform to the requirements of XML schemas that use constructs that can be expressed by data contracts. 在这种情况下,不需要 /dconly命令行选项。In this case, the /dconly command line option is not required.

如果 Svcutil.exe 工具的输入为 XML 架构,则默认情况下该工具会创建一组类。If the input to the Svcutil.exe tool is an XML schema, by default, the tool creates a set of classes. 如果对这些类进行检查,您会发现 DataContractAttribute 已经应用。If you examine those classes, you find that the DataContractAttribute has been applied. 可以使用这些类创建一个新的应用程序,用来处理必须与其他服务交换的数据。You can use those classes to create a new application to process data that must be exchanged with other services.

你还可以针对返回 Web 服务描述语言(WSDL)文档的终结点运行该工具,以自动生成用于创建 Windows Communication Foundation (WCF)客户端的代码和配置。You can also run the tool against an endpoint that returns a Web Services Description Language (WSDL) document to automatically generate the code and configuration to create an Windows Communication Foundation (WCF) client. 所生成的代码包含带有 DataContractAttribute 标记的类型。The generated code includes types that are marked with the DataContractAttribute.

重用现有类型Reusing Existing Types

数据协定具有两个基本要求:一个稳定的名称和一个成员列表。A data contract has two basic requirements: a stable name and a list of members. 该稳定名称由该协定的命名空间统一资源标识符 (URI) 和本地名称组成。The stable name consists of the namespace uniform resource identifier (URI) and the local name of the contract. 默认情况下,当你将DataContractAttribute应用到类时,它会将类名用作本地名称,并使用类的命名空间( "http://schemas.datacontract.org/2004/07/"以作为前缀)作为命名空间 URI。By default, when you apply the DataContractAttribute to a class, it uses the class name as the local name and the class's namespace (prefixed with "http://schemas.datacontract.org/2004/07/") as the namespace URI. 可通过设置 NameNamespace 属性来重写这些默认值。You can override the defaults by setting the Name and Namespace properties. 此外,还可通过将 ContractNamespaceAttribute 应用于命名空间来更改命名空间。You can also change the namespace by applying the ContractNamespaceAttribute to the namespace. 当现有类型能够完全根据您的需要处理数据,但其命名空间和类名与数据协定不同时,请使用此功能。Use this capability when you have an existing type that processes data exactly as you require but has a different namespace and class name from the data contract. 通过重写默认值,可以重用现有类型并使序列化数据符合数据协定。By overriding the default values, you can reuse your existing type and have the serialized data conform to the data contract.

备注

在任意代码中,都可以用 DataContract 一词来代替较长的 DataContractAttributeIn any code, you can use the word DataContract instead of the longer DataContractAttribute.

版本管理Versioning

数据协定还可以与其自身的后续版本兼容。A data contract can also accommodate later versions of itself. 也就是说,当协定的后续版本包含额外数据时,已存储并返回给发送方的数据将保持不变。That is, when a later version of the contract includes extra data, that data is stored and returned to a sender untouched. 为此,应实现 IExtensibleDataObject 接口。To do this, implement the IExtensibleDataObject interface.

有关版本控制的详细信息,请参阅数据协定版本控制For more information about versioning, see Data Contract Versioning.

构造函数

DataContractAttribute()

初始化 DataContractAttribute 类的新实例。Initializes a new instance of the DataContractAttribute class.

属性

IsNameSetExplicitly

获取 Name 是否已显式设置。Gets whether Name has been explicitly set.

IsNamespaceSetExplicitly

获取 Namespace 是否已显式设置。Gets whether Namespace has been explicitly set.

IsReference

获取或设置一个值,该值指示是否保留对象引用数据。Gets or sets a value that indicates whether to preserve object reference data.

IsReferenceSetExplicitly

获取 IsReference 是否已显式设置。Gets whether IsReference has been explicitly set.

Name

获取或设置类型的数据协定的名称。Gets or sets the name of the data contract for the type.

Namespace

获取或设置类型的数据协定的命名空间。Gets or sets the namespace for the data contract for the type.

TypeId

在派生类中实现时,获取此 Attribute 的唯一标识符。When implemented in a derived class, gets a unique identifier for this Attribute.

(继承自 Attribute)

方法

Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。Returns a value that indicates whether this instance is equal to a specified object.

(继承自 Attribute)
GetHashCode()

返回此实例的哈希代码。Returns the hash code for this instance.

(继承自 Attribute)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
IsDefaultAttribute()

在派生类中重写时,指示此实例的值是否是派生类的默认值。When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(继承自 Attribute)
Match(Object)

当在派生类中重写时,返回一个指示此实例是否等于指定对象的值。When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(继承自 Attribute)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
ToString()

返回一个表示当前对象的 string。Returns a string that represents the current object.

(继承自 Object)

显式界面实现

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。Maps a set of names to a corresponding set of dispatch identifiers.

(继承自 Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。Retrieves the type information for an object, which can be used to get the type information for an interface.

(继承自 Attribute)
_Attribute.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(继承自 Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。Provides access to properties and methods exposed by an object.

(继承自 Attribute)

适用于

另请参阅