Utilización de contratos de datosUsing Data Contracts

Un contrato de datos es un acuerdo formal entre un servicio y un cliente que abstractamente describe los datos que se van a intercambiar.A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. Es decir, para comunicarse, el cliente y el servicio no tienen que compartir los mismos tipos, solo los mismos contratos de datos.That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. Un contrato de datos define con precisión, para cada parámetro o tipo de valor devuelto, qué datos se serializan (se convierten en XML) para su intercambio.A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged.

Fundamentos del contrato de datosData Contract Basics

Windows Communication Foundation (WCF) utiliza un motor de serialización llamado serializador de contratos de datos de forma predeterminada para serializar y deserializar datos (convertirlos a y desde XML).Windows Communication Foundation (WCF) uses a serialization engine called the Data Contract Serializer by default to serialize and deserialize data (convert it to and from XML). Todos los tipos primitivos .NET Framework, como enteros y cadenas, así como ciertos tipos tratados como primitivos, como DateTime y XmlElement, se puede serializar sin otra preparación y se considera que tienen contratos de datos de forma predeterminada.All .NET Framework primitive types, such as integers and strings, as well as certain types treated as primitives, such as DateTime and XmlElement, can be serialized with no other preparation and are considered as having default data contracts. Muchos tipos de .NET Framework también tienen contratos de datos existente.Many .NET Framework types also have existing data contracts. Para obtener una lista completa de los tipos serializables, consulte Types Supported by the Data Contract Serializer.For a full list of serializable types, see Types Supported by the Data Contract Serializer.

Los nuevos tipos complejos que se crean deben tener un contrato de datos definido para que sean serializables.New complex types that you create must have a data contract defined for them to be serializable. De forma predeterminada, DataContractSerializer deduce el contrato de datos y serializa todos los tipos públicamente visibles.By default, the DataContractSerializer infers the data contract and serializes all publicly visible types. Se serializan todas las propiedades de lectura y escritura públicas y campos del tipo.All public read/write properties and fields of the type are serialized. Puede descartar miembros de la serialización mediante el uso de IgnoreDataMemberAttribute.You can opt out members from serialization by using the IgnoreDataMemberAttribute. También puede crear explícitamente un contrato de datos mediante el uso de los atributos DataContractAttribute y DataMemberAttribute .You can also explicitly create a data contract by using DataContractAttribute and DataMemberAttribute attributes. Esto se hace normalmente aplicando el atributo DataContractAttribute al tipo.This is normally done by applying the DataContractAttribute attribute to the type. Este atributo se puede aplicar a clases, estructuras y enumeraciones.This attribute can be applied to classes, structures, and enumerations. El atributo DataMemberAttribute se debe aplicar a continuación a cada miembro del tipo de contrato de datos para indicar que es un miembro de datos, es decir, que se debería serializar.The DataMemberAttribute attribute must then be applied to each member of the data contract type to indicate that it is a data member, that is, it should be serialized. Para obtener más información, consulte tipos serializables.For more information, see Serializable Types.

EjemploExample

En el ejemplo siguiente se muestra un contrato de servicio (una interfaz) al que se han aplicado los atributos ServiceContractAttribute y OperationContractAttribute explícitamente.The following example shows a service contract (an interface) to which the ServiceContractAttribute and OperationContractAttribute attributes have been explicitly applied. El ejemplo muestra que los tipos primitivos no requieren un contrato de datos, mientras un tipo complejo sí lo hace.The example shows that primitive types do not require a data contract, while a complex type does.

[ServiceContract]
public interface ISampleInterface
{
    // No data contract is required since both the parameter 
    // and return types are primitive types.
    [OperationContract]
    double SquareRoot(int root);

    // No Data Contract required because both parameter and return 
    // types are marked with the SerializableAttribute attribute.
    [OperationContract]
    System.Drawing.Bitmap GetPicture(System.Uri pictureUri);

    // The MyTypes.PurchaseOrder is a complex type, and thus 
    // requires a data contract.
    [OperationContract]
    bool ApprovePurchaseOrder(MyTypes.PurchaseOrder po);
}
<ServiceContract()>  _
Public Interface ISampleInterface
    ' No data contract is required since both the parameter and return 
    ' types are both primitive types.
    <OperationContract()>  _
    Function SquareRoot(ByVal root As Integer) As Double 
    
    ' No Data Contract required because both parameter and return 
    ' types are marked with the SerializableAttribute attribute.
    <OperationContract()>  _
    Function GetPicture(ByVal pictureUri As System.Uri) As System.Drawing.Bitmap 
    
    ' The MyTypes.PurchaseOrder is a complex type, and thus 
    ' requires a data contract.
    <OperationContract()>  _
    Function ApprovePurchaseOrder(ByVal po As MyTypes.PurchaseOrder) As Boolean 
End Interface 

El ejemplo siguiente muestra cómo se crea un contrato de datos para el tipo MyTypes.PurchaseOrder aplicando los atributos DataContractAttribute y DataMemberAttribute a la clase y sus miembros.The following example shows how a data contract for the MyTypes.PurchaseOrder type is created by applying the DataContractAttribute and DataMemberAttribute attributes to the class and its members.

namespace MyTypes
{
    [DataContract]
    public class PurchaseOrder
    {
        private int poId_value;

        // Apply the DataMemberAttribute to the property.
        [DataMember]
        public int PurchaseOrderId
        {

            get { return poId_value; }
            set { poId_value = value; }
        }
    }
}
Namespace MyTypes
    <System.Runtime.Serialization.DataContractAttribute()>  _
    Public Class PurchaseOrder
        Private poId_value As Integer
        
        ' Apply the DataMemberAttribute to the property.
        
        <DataMember()>  _
        Public Property PurchaseOrderId() As Integer 
            
            Get
                Return poId_value
            End Get
            Set
                poId_value = value
            End Set
        End Property
    End Class 
End Namespace 

NotasNotes

Las notas siguientes proporcionan los elementos a considerar al crear los contratos de datos:The following notes provide items to consider when creating data contracts:

  • El atributo IgnoreDataMemberAttribute se observa solo cuando se usa con tipos no marcados.The IgnoreDataMemberAttribute attribute is only honored when used with unmarked types. Se incluyen los tipos que no están marcados con uno de los atributos DataContractAttribute, SerializableAttribute, CollectionDataContractAttributeo EnumMemberAttribute , o que están marcados como serializables de alguna otra forma (como IXmlSerializable).This includes types that are not marked with one of the DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute, or EnumMemberAttribute attributes, or marked as serializable by any other means (such as IXmlSerializable).

  • Puede aplicar el atributo DataMemberAttribute a campos y propiedades.You can apply the DataMemberAttribute attribute to fields, and properties.

  • Los niveles (interno, privado, protegido o público) de accesibilidad de miembros no afectan de forma alguna al contrato de datos.Member accessibility levels (internal, private, protected, or public) do not affect the data contract in any way.

  • Se omite el atributo DataMemberAttribute si se aplica a los miembros estáticos.The DataMemberAttribute attribute is ignored if it is applied to static members.

  • Durante la serialización, se llama al código de obtención de propiedades para que los miembros de datos de propiedad obtengan el valor de las propiedades a serializar.During serialization, property-get code is called for property data members to get the value of the properties to be serialized.

  • Durante la deserialización, primero se crea un objeto no inicializado, sin llamar a ningún constructor en el tipo.During deserialization, an uninitialized object is first created, without calling any constructors on the type. A continuación, se deserializan todos los miembros de datos.Then all data members are deserialized.

  • Durante la serialización, se llama al código de conjunto de propiedades para que los miembros de datos de propiedad establezcan el valor de las propiedades que se están deserializando.During deserialization, property-set code is called for property data members to set the properties to the value being deserialized.

  • Para que un contrato de datos sea válido, debe ser posible serializar todos sus miembros de datos.For a data contract to be valid, it must be possible to serialize all of its data members. Para obtener una lista completa de los tipos serializables, consulte Types Supported by the Data Contract Serializer.For a full list of serializable types, see Types Supported by the Data Contract Serializer.

    Los tipos genéricos se administran exactamente de la misma manera como los tipos no genéricos.Generic types are handled in exactly the same way as non-generic types. No hay ningún requisito especial para los parámetros genéricos.There are no special requirements for generic parameters. Por ejemplo, veamos el siguiente tipo.For example, consider the following type.

[DataContract]
public class MyGenericType1<T>
{
    // Code not shown.
}
<DataContract()>  _
Public Class MyGenericType1(Of T)
    ' Code not shown.
End Class

Este tipo es serializable tanto si el tipo que se usa para el parámetro de tipo genérico (T) es serializable como si no lo es.This type is serializable whether the type used for the generic type parameter (T) is serializable or not. Dado que debe ser posible serializar todos los miembros de datos, el tipo siguiente solo es serializable solo si el parámetro de tipo genérico también es serializable, como se muestra en el código siguiente.Because it must be possible to serialize all data members, the following type is serializable only if the generic type parameter is also serializable, as shown in the following code.

[DataContract]
public class MyGenericType2<T>
{
    [DataMember]
    T theData;
}
<DataContract()>  _
Public Class MyGenericType2(Of T)
    <DataMember()>  _
    Dim theData As T
End Class 

Para obtener un ejemplo de código completo de un servicio WCF que define un contrato de datos, consulte el ejemplo de Basic Data Contract .For a complete code sample of a WCF service that defines a data contract see the Basic Data Contract sample.

Vea tambiénSee also