WCF – Service Contracts, Data Contracts y Message Contracts

Service Contract

l  Define lo que puede hacer un servicio.

l  Permite la interoperabilidad de un servicio.

Un contrato no es más ni menos que un acuerdo entre las partes involucradas, que define la manera en que se va a trabajar y con qué elementos. En este caso se especificará qué funciones se van a ofrecer, qué tipos de datos se van a recibir o enviar, y cómo van a ser enviados.

Los contratos son conceptos fundamentales a la hora de trabajar con WCF. Éstos permiten que los clientes y los servicios tengan el mismo conocimiento de las operaciones ofrecidas, las estructuras de datos y la estructura de los mensajes.

Para cada tipo de información del servicio proporcionado, existe una clasificación de contratos:

Service Contract: describe las operaciones que ofrece un servicio.

Data Contract: describe las estructuras de datos manejadas por las operaciones del servicio.

Message Contract: define el contenido de un mensaje, ya sea en la cabecera o en el cuerpo.

Conversión de los contratos a un formato de plataforma independiente.

serviceContract

Los contratos son definidos por el CLR por medio de clases o interfaces. Éstas, al ser utilizadas en los servicios, son convertidas a un formato común para que el servicio pueda ser usado por distintas plataformas con total compatibilidad.

Definir Service Contract

Service Contract describe las operaciones que provee un servicio. Convierte los métodos de la interfaz de un servicio en una descripción de plataforma independiente (WSDL), y define el patrón de mensajes utilizado en el servicio.

Un Service Contract se puede definir de dos maneras:

          Por medio de una interfaz con el atributo [ServiceContract]. Se identifican sus operaciones con el atributo [OperationContract].

          Por medio de una clase en la cual, al declarar la clase, se deberá escribir el atributo [ServiceContract], y a cada uno de sus métodos, el atributo [OperationContract].

Definir Service Contract en una interfaz

Demo:

namespace RMS.Service.Contracts

{

    [ServiceContract(SessionMode=SessionMode.Required)]

    public interface Iwcftest

    {

        [OperationContract]

        VendorContract[] GetVendors();

    }

}

[ServiceContract] – Parámetros opcionales

CallbackContract (type): es utilizado cuando el patrón de mensajes es Duplex (es decir, de dos vías de comunicación).

El contrato del cliente de llama Callback Contract.

Por default, no se encuentra habilitado.

FormatMode(ContractFormatMode): selecciona un serializer. Un serializer es una clase que se encarga de la serialización y deserialización de los datos. El predeterminado es XmlFormatter.

Name(string): define el nombre del contrato. En caso de omitirlo, le asigna el nombre de la clase o interfaz.

NameSpace: define el namespace del contrato. En caso de omitirlo, le asigna el namespace de la clase o interfaz.

Session(boolean): indica si el contrato requiere una sesión.

Style(ServiceOperationStye): indica la manera en que el WSDL Metadata puede ser convertido:

          document/wrapped,

          document/bare,

          RPC message.

Si se desea cambiar el estilo del formato, puede hacerse tanto en el atributo [ServiceContract], que afecta a todas las operaciones del contrato, como en [OperationContract], que afecta a la operación definida.

Use: determina si el mensaje será codificado (encoded) o no (literal). En caso de ser codificado, también se deberá indicar el serializador utilizado. Este parámetro puede ser utilizado a nivel del contrato completo ([ServiceContract]) o a nivel de una operación ([OperationContract]).

[OperationContract] – Parámetros opcionales

Action(string): indica el nombre de la operación que será ejecutada por el servicio. En el caso de un servicio no tipado, si se especifica *, traerá todas las operaciones del servicio.

AsyncPattern(boolean): determina si la operación se ejecuta de manera asincrónica o sincrónica. En el caso de que opere de manera sincrónica, al llamar a la operación, el cliente se bloquea esperando a que la operación termine. En este caso utiliza un patrón de mensajes Duplex.

Si, en cambio, opera de manera asincrónica, al llamar a la operación, el cliente no tiene que esperar a que ésta termine y, mientras tanto, puede ejecutar otras tareas.

IsOneWay(boolean): indica si la operación trabaja en una dirección (true) o en dos direcciones (false).

Al comunicarse en una dirección (con el patrón de mensajes Simplex), trabaja de manera asincrónica, ya que al llamar a la operación, el cliente puede realizar otras tareas, porque no recibe ninguna respuesta que indique la finalización de ésta.

Al trabajar en dos direcciones (con el patrón de mensajes Duplex), lo hace de manera sincrónica, ya que al llamar a la operación, el cliente debe esperar a que ésta se ejecute por completo para realizar otras tareas. Esto se debe a que antes debe recibir la confirmación o el resultado de su ejecución.

IsInitiating(boolean): determina cuándo se inicializará un nuevo canal. El predeterminado es true.

IsTerminating(boolean): determina cuándo la operación será cerrada y se eliminará el canal utilizado por el cliente.

Name(string): define el nombre de la operación.

ReplyAction(string): es un URI, que especifica la acción de respuesta a una solicitud de la operación. En caso de no utilizar esta propiedad, el URI tomará el siguiente valor: “http://tempuri.org/contract-name/operation-nameRespons”.

Style(ServiceOperationStyle): indica la manera en que el WSDL Metadata puede ser convertido:

          document/wrapped,

          document/bare,

          RPC message.

Si se desea cambiar el estilo del formato, puede hacerse tanto en el atributo [ServiceContract], afectando a todas las operaciones del contrato, o en [OperationContract], afectando a la operación definida.

Use(ServiceOperationBindingUse): determina si el mensaje será codificado (encoded) o no (literal). En el caso de ser codificado, también se deberá indicar el serializador utilizado. Este parámetro puede ser utilizado a nivel del contrato completo ([ServiceContract]) o a nivel de una operación ([OperationContract]).

Data Contract

El Data Contract describe la estructura de datos que es manejada por las funciones del servicio.

También, con el Data Contract es posible especificar la estructura del tipo de datos que intercambia el servicio.

Permite, a la vez, convertir la estructura definida anteriormente en un XML Schema, el cual es un esqueleto de tipo datos y es un formato independiente de la plataforma utilizada.

Por último, define cómo se tienen que serializar y deserializar los nuevos datos.

Con el atributo [DataContract] es posible definir un contrato de datos para una clase, estructura o enumeración, y así establecer el tipo de datos para recibir o enviar.

El atributo [DataMember] permite definir los tipos de datos.

Demo:

namespace RMS.Service.DataContracts

{

    [DataContract]

    public class VendorContract:IExtensibleDataObject

    {

        #region IExtensibleDataObject Members

 

        public ExtensionDataObject ExtensionData

        {

            get;           

            set;           

        }

 

        #endregion        

 

        #region IDataContract Members

 

        [DataMember]

        public string Code { get; set; }

 

        [DataMember]

        public string Name { get; set; }

 

        [DataMember]

        public string Image { get; set; }

 

        [DataMember]

        public string Description { get; set; }

 

        [DataMember]

        public bool Active { get; set; }

 

        #endregion

    }

}

[DataContract] – Parámetros

l  NameSpace(Uri)

Ø  Especifica el namespace del contrato.

l  Name(string)

Ø  Define el nombre del contrato.

[DataMember] – Parámetros

IsOptional(boolean): controla qué sucede si datos que son recibidos no se encuentran en el Data Contract. Si el campo es false, no habrá problemas y seguirá adelante; en caso contrario, lanzará un error.

OBSERVACIÓN

Es importante no confundir IsOptional con MustUnderstand. Cuando se habla de IsOptional, se hace referencia a algo que el receptor especifica. MustUnderstand, en cambio, se refiere a algo que especifica el lado que envía los datos.

MustUnderstand(boolean): al enviar los datos se espera que el receptor entienda el campo enviado. Indica qué ocurre cuando el receptor recibe un grupo de datos en el cual hay un miembro que no está en el Data Contract del receptor, y si es obligatorio que el receptor entienda ese campo o no.

Name(string): indica el nombre del Data Contract.

VersionAdded(int): para documentar los cambios en el Data Contract se pueden asignar números de versión a los DataMembers.

SerializeAs(SerializationReferenceMode): controla qué sucede cuando dos miembros del Data Contract referencian la misma instancia de un objeto.

Cuando la clase del Data Contract es serializada, más de un miembro puede tener la misma referencia a un objeto. En ese caso, la serialización puede realizarse de dos maneras:

          ReferenceType: al serializar y deserializar el Data Contract, los miembros siguen con las referencias compartidas.

          ValueType: al serializar y deserializar el Data Contract, cada miembro tendrá su propia referencia al objeto, sin importar si dos miembros referencian objetos iguales.

Por default, se especifica ReferenceType.

About justindeveloper

I am MCP (Microsoft Certified Professional). MCTS (Microsoft Certified Technology Specialist) and MCPD (Microsoft Certified Professional Developer), also I am SAP Business One Certified!! Desarrollando desde el IDE de Visual Studio NET 2003 hasta ahora con el Visual Studio NET 2010. Desde Microsoft SQL Server 2000 hasta ahora con el Microsoft SQL Server 2008 R2 y tambien con SharePoint, desde WSS 3.0 y MOSS 2007 y ahora familirizandome con el Sharepoint Foundation 2010 & Sharepoint Server 2010. The software development will follow being every time more wonderful!
This entry was posted in Development. Bookmark the permalink.

One Response to WCF – Service Contracts, Data Contracts y Message Contracts

  1. Ronald says:

    Muy buena explicación introductoria. Muchas gracias.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s