Usar acciones OData para implementar el comportamiento del lado servidor

El Open Data Protocol (OData) le permite definir una acción de servicio en un servicio de datos. Una acción de servicio es una operación especial definida en un servicio de datos. Las acciones de servicio proporcionan una forma de insertar comportamientos en un modelo centrado en datos. Las acciones de servicio le permiten invocar lógica de negocios en OData, donde la lógica debe estar enlazada a un recurso determinado. Las acciones de servicio se diferencian de las operaciones de servicio normales basadas en extremos de las maneras siguientes:

  • Enlazadas a recursos

    A diferencia de las operaciones de servicio que se definen en un extremo fijo, las acciones de servicio suelen estar enlazadas a recursos, conjuntos de entidades (fuentes) o entidades individuales. Estos recursos se denominan parámetros de enlace. En WCF Data Services, los parámetros de enlace solo pueden ser tipos de entidad y colecciones de tipos de entidad. También se pueden suministrar parámetros no de enlace a las acciones de servicio. Sin embargo, estos parámetros solo pueden ser de un tipo primitivo, un tipo complejo, o una colección de tipos primitivos o complejos. Cuando una acción de servicio se enlaza a un recurso, se expone en la serialización de entidades como un recurso de acción.

  • Tienen efectos secundarios

    La lógica de negocios invocada por una acción de servicio afecta al sistema, por ejemplo cambiando datos o el estado, o invocando algún otro proceso de negocio. Como las acciones de servicio siempre tienen efectos secundarios, solo se pueden invocar mediante una solicitud POST. A diferencia de las operaciones de servicio, los parámetros que no son de enlace se suministran a las acciones de servicio en el cuerpo del mensaje, no en el URI. Estos parámetros que no son de enlace se proporcionan como valores codificados con notación JavaScript (JSON) en el cuerpo de la solicitud.

  • No se pueden componer más

    Las acciones de servicio pueden tener los mismos tipos de valores devueltos que las operaciones de servicio. Sin embargo, a diferencia de las operaciones de servicio, las acciones de servicio no se pueden componer más. Esto significa que las opciones de consulta del sistema no se pueden aplicar a una acción de servicio.

Considere una película digital como un recurso; se pueden hacer muchas cosas con una película digital: desproteger, valorar/comentar o proteger. Todos estos son ejemplos de acciones que se pueden implementar mediante un Servicio de datos de WCF que administre películas digitales. Las acciones se describen en una respuesta OData que contiene un recurso en el que se puede invocar la acción. Cuando un usuario solicita un recurso que representa una película digital, la respuesta devuelta por el Servicio de datos de WCF contiene información sobre las acciones disponibles para dicho recurso. La disponibilidad de una acción puede depender del estado del servicio de datos o del recurso. Por ejemplo, una vez desprotegida una película digital otro usuario no la puede desproteger. Los clientes pueden invocar una acción con solo especificar una dirección URL. Por ejemplo, http://MiServidor/MovieService.svc/Movies(6) identificaría una película digital concreta y http://MiServidor/MovieService.svc/Movies(6)/Checkout invocaría la acción en esa película específica. Las acciones le permiten exponer su modelo de servicio sin exponer el modelo de datos. Continuando con el ejemplo de servicio de películas, quizás desee permitir que un usuario valore una película pero no desee exponer directamente los datos de valoración como un recurso. Podría implementar una acción de valoración que permitiera al usuario valorar una película pero no tener acceso directamente a los datos de valoración como un recurso.

Implementar una acción

Para implementar una acción de servicio debe implementar las interfaces IServiceProvider, IDataServiceActionProvider y IDataServiceInvokable. IServiceProvider permite que WCF Data Services obtenga su implementación de IDataServiceActionProvider. IDataServiceActionProvider permite que WCF Data Services cree, busque, describa e invoque acciones de servicio. IDataServiceInvokable le permite invocar el código que implementa el comportamiento de las acciones de servicio y obtener los resultados, si hay alguno. Tenga en cuenta que WCF Data Services son Servicios de WCF por llamada; se creará una nueva instancia del servicio cada vez que se llame al servicio. Asegúrese de que no se realiza trabajo innecesario cuando se crea el servicio.

IServiceProvider

IServiceProvider contiene un método denominado GetService(Type). WCF Data Services llama a este método para recuperar una serie de proveedores de servicios, incluidos proveedores de servicios de metadatos y proveedores de acciones de servicios de datos. Cuando se le pida un proveedor de acciones de servicios de datos, devuelva su implementación de IDataServiceActionProvider.

IDataServiceActionProvider

IDataServiceActionProvider contiene métodos que permiten recuperar información sobre las acciones disponibles. Al implementar IDataServiceActionProvider se aumentan los metadatos para el servicio definidos por la implementación del servicio de IDataServiceMetadataProvider con acciones y control de envío a esas acciones según corresponda.

AdvertiseServiceAction

Se llama a AdvertiseServiceAction(DataServiceOperationContext, ServiceAction, Object, Boolean, ODataAction%) para determinar qué acciones hay disponibles para el recurso especificado. Solo se llama a este método para las acciones que no están siempre disponibles. Se emplea para comprobar si la acción se debe incluir en la respuesta OData según el estado del recurso que se solicita o el estado del servicio. Usted decide cómo se realiza esta comprobación. Si resulta costoso calcular la disponibilidad y el recurso actual está en una fuente, es aceptable omitir la comprobación y anunciar la acción. El parámetro inFeed se establece en true si el recurso actual que se devuelve forma parte de una fuente.

CreateInvokable

Se llama a CreateInvokable(DataServiceOperationContext, ServiceAction, array<Object[]) para crear una IDataServiceInvokable que contiene un delegado que encapsula el código que implementa el comportamiento de la acción. Esto crea la instancia de IDataServiceInvokable pero no invoca la acción. Las acciones de un Servicio de datos de WCF tienen efectos secundarios y deben usarse junto con el proveedor de actualizaciones para guardar estos cambios en disco. Se llama al método Invoke() desde el método SaveChanges() del proveedor de actualizaciones.

GetServiceActions

Este método devuelve una colección de instancias de ServiceAction que representan todas las acciones que un Servicio de datos de WCF expone. ServiceAction es la representación de metadatos de una acción, que incluye información como el nombre de acción, sus parámetros y su tipo de valor devuelto.

GetServiceActionsByBindingParameterType

Este método devuelve una colección de todas las instancias de ServiceAction que se pueden enlazar al tipo de parámetro de enlace especificado. Es decir, todos los ServiceAction que pueden actuar en el tipo de recurso especificado (conocido también como tipo de parámetro de enlace). Esto se usa cuando el servicio devuelve un recurso para incluir información sobre las acciones que se pueden invocar en dicho recurso. Este método solo debe devolver acciones que se pueden enlazar al tipo de parámetro de enlace exacto (no a tipos derivados). Se llama a este método una vez por solicitud por tipo encontrado y WCF Data Services almacena en memoria caché el resultado.

TryResolveServiceAction

Este método busca un ServiceAction especificado y devuelve true si se encuentra ServiceAction. Si se encuentra, se devuelve ServiceAction en el parámetro serviceAction out.

IDataServiceInvokable

Esta interfaz proporciona una forma de ejecutar una acción de un Servicio de datos de WCF. A la hora de implementar IDataServiceInvokable, es responsable de 3 cosas:

  1. Capturar y posiblemente calcular las referencias de los parámetros

  2. Enviar los parámetros al código que implementa realmente la acción cuando se llama a Invoke()

  3. Almacenar los resultados de Invoke() para que se puedan recuperar mediante GetResult()

Los parámetros se pueden pasar como tokens. Esto se debe a que es posible escribir un proveedor de servicios de datos que funcione con tokens que representan recursos; en este caso, quizás necesite convertir (calcular las referencias) estos tokens en recursos reales antes de enviarlos a la acción real. Una vez calculadas las referencias del parámetro, este debe estar en un estado editable para que se guarde y se escriba en disco cualquier cambio realizado en el recurso cuando se invoque la acción.

Esta interfaz necesita dos métodos: Invoke y GetResult. Invoke invoca el delegado que implementa el comportamiento de la acción y GetResult devuelve el resultado de la acción.

Control de acceso a las acciones de servicio

En Servicios de datos de Microsoft WCF, el método SetServiceActionAccessRule(String, ServiceActionRights) de la clase IDataServiceConfiguration controla la visibilidad de las acciones de servicio en todo el servicio, de la misma forma que el método SetServiceOperationAccessRule(String, ServiceOperationRights) controla la visibilidad de las operaciones de servicio.

Definición de metadatos de las acciones de servicio

Igual que las operaciones de servicio, las acciones de servicio se definen como elementos FunctionImport en los metadatos del servicio. Una acción de servicio FunctionImport contiene cero o más elementos Parameter, que representan tanto parámetros de enlace como parámetros que no son de enlace. Además, los siguientes atributos de FunctionImport definen el comportamiento de la acción de servicio:

  • IsSideEffecting

    Como las acciones de servicio siempre pueden tener efectos secundarios, este atributo es siempre true.

  • IsBindable

    Las acciones de servicio suelen estar enlazadas a un recurso, aunque no siempre lo están. Cuando este atributo es true, el primer parámetro debe ser un tipo de entidad o una colección de entidades.

  • IsComposable

    Puesto que las acciones de servicio no admiten composición de consultas adicional, este atributo es siempre false.

Invocar una acción de un Servicio de datos de WCF

Las acciones se invocan mediante una solicitud POST HTTP. La dirección URL especifica el recurso seguido del nombre de la acción. Los parámetros se pasan en el cuerpo de la solicitud. Por ejemplo, suponga que hay un servicio denominado MovieService que expone una acción denominada Rate. Puede usar la dirección URL siguiente para invocar la acción Rate en una película concreta:

http://MovieServer/MovieService.svc/Movies(1)/Rate

Movies(1) especifica la película que desea valorar y Rate especifica la acción Rate. El valor real de la valoración estará en el cuerpo de la solicitud HTTP como se muestra en el ejemplo siguiente:

POST http://MovieServer/MoviesService.svc/Movies(1)/Rate HTTP/1.1 
Content-Type: application/json 
Content-Length: 20 
Host: localhost:15238
{ 
   "rating": 4 
}

Advertencia

El código muestra anterior solo funcionará con WCF Data Services 5.2 y versiones posteriores que admitan JSON ligero.Si emplea una versión anterior de WCF Data Services, debe especificar el content-type detallado de json de la manera siguiente: application/json;odata=verbose.

O bien, puede invocar una acción mediante el Cliente de WCF Data Services como se muestra en el fragmento de código siguiente.

MoviesModel context = new MoviesModel (new Uri("http://MyServer/MoviesService.svc/"));
            //...
            context.Execute(new Uri("http://MyServer/MoviesService.svc/Movies(1)/Rate"), "POST", new BodyOperationParameter("rating",4) );         

En el fragmento de código anterior, la clase MoviesModel se generaba usando Visual Studio para Agregar referencia de servicio a un Servicio de datos de WCF.

Vea también

Conceptos

Desarrollar e implementar WCF Data Services

Proveedores de servicios de datos personalizados (WCF Data Services)

Otros recursos

WCF Data Services

Servicio de datos (WCF Data Services)