Compartir a través de


Operaciones de servicio (WCF Data Services)

Servicios de datos de Microsoft WCF le permite definir operaciones de servicio en un servicio de datos para exponer métodos del servidor. Las operaciones de servicio se direccionan como los demás recursos del servicio de datos, mediante los URI. Las operaciones de servicio le permiten exponer la lógica de negocios de un servicio de datos; por ejemplo, implementar la lógica de validación, aplicar la seguridad basada en roles o exponer capacidades de consulta especializadas. Las operaciones de servicio son métodos agregados a la clase de servicio de datos que deriva de DataService<T>. Al igual que otros recursos de servicio de datos, puede proporcionar los parámetros al método de la operación de servicio. Por ejemplo, el siguiente URI de operación de servicio (basado en el servicio de datos quickstart) pasa el valor London al parámetro city:

https://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'

La definición de esta operación de servicio es la siguiente:

<WebGet()> _
Public Function GetOrdersByCity(ByVal city As String) As IQueryable(Of Order)
[WebGet]
public IQueryable<Order> GetOrdersByCity(string city)

Puede usar la propiedad CurrentDataSource de la clase DataService<T> para tener acceso directo al origen de datos que está usando el servicio de datos. Para obtener más información, vea Cómo: Definir una operación de servicio (WCF Data Services).

Para obtener información sobre cómo llamar a una operación de servicio desde una aplicación cliente de .NET Framework, vea Llamar a operaciones y acciones de servicio (WCF Data Services).

Requisitos que deben cumplir las operaciones de servicio

Al definir operaciones de servicio en el servicio de datos deben tenerse en cuenta los requisitos siguientes. Si un método no los cumple, no se expondrá como operación de servicio para el servicio de datos.

  • La operación debe ser un método de instancia pública que sea miembro de la clase del servicio de datos.

  • El método de la operación solo puede aceptar parámetros de entrada. El servicio de datos no puede tener acceso a los datos enviados en el cuerpo del mensaje.

  • Si se definen parámetros, el tipo de cada parámetro debe ser un tipo primitivo. Cualquier dato de un tipo no primitivo se debe serializar y pasar a un parámetro de cadena.

  • El método debe devolver uno de los elementos siguientes:

    • void (Nothing en Visual Basic)

    • IEnumerable<T>

    • IQueryable<T>

    • Un tipo de entidad en el modelo de datos expuesto por el servicio de datos.

    • Una clase primitiva como entero o cadena.

  • Para admitir opciones de consulta como ordenaciones, paginaciones y filtrados, los métodos de las operaciones de servicio deben devolver IQueryable<T>. Las solicitudes a operaciones de servicio que incluyen opciones de consulta se rechazan para las operaciones que solo devuelven IEnumerable<T>.

  • Para que se pueda tener acceso a las entidades relacionadas usando las propiedades de navegación, la operación de servicio debe devolver IQueryable<T>.

  • El método se debe anotar con el atributo [WebGet] o [WebInvoke].

    • [WebGet] permite invocar el método usando una solicitud GET.

    • [WebInvoke(Method = "POST")] permite invocar el método usando una solicitud POST. No se admiten otros métodos WebInvokeAttribute.

  • Una operación de servicio se puede anotar con el elemento SingleResultAttribute que especifica que el valor devuelto desde el método es una sola entidad en vez de una colección de entidades. Esta distinción dicta la serialización resultante de la respuesta y la manera en que se representan en el URI los recorridos de las propiedades de navegación adicionales. Por ejemplo, cuando use la serialización AtomPub, una sola instancia de tipo de recurso se representa como elemento de entrada y un conjunto de instancias como elemento de fuente.

Direccionar operaciones de servicio

Puede direccionar las operaciones de servicio colocando el nombre del método en el primer segmento de la ruta de acceso de un URI. Como ejemplo, el siguiente URI tiene acceso a una operación GetOrdersByState que devuelve una colección IQueryable<T> de objetos Orders.

https://localhost:12345/Northwind.svc/GetOrdersByState?state='CA'&includeItems=true

Al llamar a una operación de servicio, los parámetros se proporcionan como opciones de consulta. La operación de servicio anterior acepta tanto un parámetro de cadena state como un parámetro booleano includeItems que indica si se van a incluir objetos Order_Detail relacionados en la respuesta.

A continuación se enumeran los tipos de valor devueltos válidos para una operación de servicio:

Tipos de valor devueltos válidos

Reglas que deben cumplir los URI

void (Nothing en Visual Basic)

o bien

Tipos de entidad

o bien

Tipos primitivos

El URI debe ser un solo segmento de ruta de acceso que sea el nombre de la operación de servicio. No se permiten las opciones de consulta.

IEnumerable<T>

El URI debe ser un solo segmento de ruta de acceso que sea el nombre de la operación de servicio. Puesto que el tipo de resultado no es un tipo IQueryable<T>, no se permiten las opciones de consulta.

IQueryable<T>

Se permiten segmentos de ruta de acceso de la consulta además de la ruta de acceso que es el nombre de la operación de servicio. También se permiten las opciones de consulta.

Se pueden agregar segmentos de ruta de acceso u opciones de consulta adicionales al URI en función del tipo de valor devuelto de la operación de servicio. Por ejemplo, el URI siguiente tiene acceso a una operación GetOrdersByCity que devuelve una colección IQueryable<T> de objetos Orders, ordenada en orden descendente por RequiredDate, junto con los objetos Order_Details relacionados:

https://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'&$expand=Order_Details&$orderby=RequiredDate desc

Control de acceso a las operaciones de servicio

El método SetServiceOperationAccessRule de la clase IDataServiceConfiguration controla la visibilidad en el ámbito de todos los servicios de las operaciones de servicio, de la misma forma que el método SetEntitySetAccessRule controla la visibilidad del conjunto de entidades. Por ejemplo, la línea de código siguiente de la definición del servicio de datos permite el acceso a la operación de servicio CustomersByCity.

config.SetServiceOperationAccessRule( _
    "GetOrdersByCity", ServiceOperationRights.AllRead)
config.SetServiceOperationAccessRule(
    "GetOrdersByCity", ServiceOperationRights.AllRead);

Nota

Si una operación de servicio tiene un tipo de valor devuelto que se oculta restringiendo el acceso en los conjuntos de entidades subyacentes, la operación de servicio no estará disponible para las aplicaciones cliente.

Para obtener más información, vea Cómo: Definir una operación de servicio (WCF Data Services).

Producir excepciones

Recomendamos utilizar la clase DataServiceException cada vez que produzca una excepción en la ejecución del servicio de datos. Esto es porque el tiempo de ejecución del servicio de datos sabe cómo asignar correctamente propiedades de este objeto de excepción al mensaje de respuesta HTTP. Al generar una DataServiceException en una operación de servicio, la excepción devuelta está contenida en TargetInvocationException. Para devolver la DataServiceException base sin la TargetInvocationException envolvente, debe invalidar el método HandleException(HandleExceptionArgs) en DataService<T>, extraer DataServiceException de TargetInvocationException y devolverlo como el error de nivel superior, como en el siguiente ejemplo:

' Override to manage returned exceptions.
Protected Overrides Sub HandleException(args As HandleExceptionArgs)
    ' Handle exceptions raised in service operations.
    If args.Exception.GetType() = GetType(TargetInvocationException) _
        AndAlso args.Exception.InnerException IsNot Nothing Then
        If args.Exception.InnerException.GetType() = GetType(DataServiceException) Then
            ' Unpack the DataServiceException.
            args.Exception = _
                TryCast(args.Exception.InnerException, DataServiceException)
        Else
            ' Return a new DataServiceException as "400: bad request."
            args.Exception = _
                New DataServiceException(400, args.Exception.InnerException.Message)
        End If
    End If
End Sub
// Override to manage returned exceptions.
protected override void HandleException(HandleExceptionArgs args)
{
    // Handle exceptions raised in service operations.
    if (args.Exception.GetType() ==
        typeof(TargetInvocationException)
        && args.Exception.InnerException != null)
    {
        if (args.Exception.InnerException.GetType()
            == typeof(DataServiceException))
        {

            // Unpack the DataServiceException.
            args.Exception = args.Exception.InnerException as DataServiceException;

        }
        else
        {
            // Return a new DataServiceException as "400: bad request."
            args.Exception =
                new DataServiceException(400,
                    args.Exception.InnerException.Message);
        }
    }
}

Vea también

Conceptos

Interceptores (WCF Data Services)