Para ver el artículo en inglés, active la casilla Inglés. También puede ver el texto en inglés en una ventana emergente si pasa el puntero del mouse por el texto.
Traducción
Inglés

Utilización de contratos de datos

 

Un contrato de datos es un acuerdo formal entre un servicio y un cliente que abstractamente describe los datos que se van a intercambiar. Es decir, para comunicarse, el cliente y el servicio no tienen que compartir los mismos tipos, solo los mismos contratos de datos. 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.

Windows Communication Foundation (WCF) utiliza un motor de la serialización llamado Serializador de contrato de datos de forma predeterminada para serializar y deserializar los datos (convertirlos de y a XML). Todos los tipos primitivos .NET Framework, como enteros y cadenas, así como ciertos tipos tratados como primitivos, como DateTime y XmlElement, se pueden serializar sin otra preparación y se considera que tienen contratos de datos predeterminados. Muchos tipos .NET Framework también tienen contratos de datos existentes. Para obtener una lista completa de los tipos serializables, consulte Tipos admitidos por el serializador de contrato de datos.

Los nuevos tipos complejos que se crean deben tener un contrato de datos definido para que sean serializables. De forma predeterminada, DataContractSerializer deduce el contrato de datos y serializa todos los tipos públicamente visibles. Se serializan todas las propiedades de lectura y escritura públicas y campos del tipo. Puede descartar miembros de la serialización mediante el uso de IgnoreDataMemberAttribute. También puede crear explícitamente un contrato de datos mediante el uso de los atributos DataContractAttribute y DataMemberAttribute. Esto se hace normalmente aplicando el atributo DataContractAttribute al tipo. Este atributo se puede aplicar a clases, estructuras y enumeraciones. 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.Para obtener más información, consulte Tipos serializables.

En el ejemplo siguiente se muestra un contrato de servicio (una interfaz) al que se han aplicado los atributos ServiceContractAttribute y OperationContractAttribute explícitamente. El ejemplo muestra que los tipos primitivos no requieren un contrato de datos, mientras un tipo complejo sí lo hace.

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

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.

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

Las notas siguientes proporcionan los elementos a considerar al crear los contratos de datos:

  • El atributo IgnoreDataMemberAttribute se observa solo cuando se usa con tipos no marcados. Se incluyen los tipos que no están marcados con uno de los atributos DataContractAttribute, SerializableAttribute, CollectionDataContractAttribute o EnumMemberAttribute, o que están marcados como serializables de alguna otra forma (como IXmlSerializable).

  • Puede aplicar el atributo DataMemberAttribute a campos y propiedades.

  • Los niveles (interno, privado, protegido o público) de accesibilidad de miembros no afectan de forma alguna al contrato de datos.

  • Se omite el atributo DataMemberAttribute si se aplica a los miembros estáticos.

  • 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.

  • Durante la deserialización, primero se crea un objeto no inicializado, sin llamar a ningún constructor en el tipo. A continuación, se deserializan todos los miembros de datos.

  • 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.

  • Para que un contrato de datos sea válido, debe ser posible serializar todos sus miembros de datos. Para obtener una lista completa de los tipos serializables, consulte Tipos admitidos por el serializador de contrato de datos.

    Los tipos genéricos se administran exactamente de la misma manera como los tipos no genéricos. No hay ningún requisito especial para los parámetros genéricos. Por ejemplo, veamos el siguiente tipo.

[DataContract]
public class MyGenericType1<T>
{
    // Code not shown.
}

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. 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.

[DataContract]
public class MyGenericType2<T>
{
    [DataMember]
    T theData;
}

Para obtener un ejemplo de código completo de un servicio WCF que define un contrato de datos, consulte el ejemplo de Contrato de datos básico.

Mostrar: