Share via


Cómo: Interceptar mensajes del servicio de datos (WCF Data Services)

Con WCF Data Services , puede interceptar mensajes de solicitud, lo que le permitirá agregar lógica personalizada a una operación. Para interceptar un mensaje, se usan métodos con atributos especiales con el servicio de datos. Para obtener más información, vea Interceptores (WCF Data Services).

En el ejemplo de este tema se usa el servicio de datos de ejemplo Northwind. Este servicio se crea cuando se completa el Tutorial rápido de WCF Data Services.

Para definir un interceptor de consultas para el conjunto de entidades Orders

  1. En el proyecto del servicio de datos de Northwind, abra el archivo Northwind.svc.

  2. En la página de código de la clase Northwind, agregue la instrucción using siguiente (Imports en Visual Basic).

    Imports System.Linq.Expressions
    
    using System.Linq.Expressions;
    
  3. En la clase Northwind, defina un método de operación de servicio denominado OnQueryOrders como sigue:

    ' Define a query interceptor for the Orders entity set.
    <QueryInterceptor("Orders")> _
    Public Function OnQueryOrders() As Expression(Of Func(Of Order, Boolean))
    
    // Define a query interceptor for the Orders entity set.
    [QueryInterceptor("Orders")]
    public Expression<Func<Order, bool>> OnQueryOrders()
    

Para definir un interceptor de cambios para el conjunto de entidades Products

  1. En el proyecto del servicio de datos de Northwind, abra el archivo Northwind.svc.

  2. En la clase Northwind, defina un método de operación de servicio denominado OnChangeProducts como sigue:

    ' Define a change interceptor for the Products entity set.
    <ChangeInterceptor("Products")> _
    Public Sub OnChangeProducts(ByVal product As Product, _
                                ByVal operations As UpdateOperations)
    
    // Define a change interceptor for the Products entity set.
    [ChangeInterceptor("Products")]
    public void OnChangeProducts(Product product, UpdateOperations operations)
    

Ejemplo

En este ejemplo se define un método de interceptor de consultas para el conjunto de entidades Orders que devuelve una expresión lambda. Esta expresión contiene un delegado que filtra los pedidos (Orders) solicitados basándose en los clientes (Customers) relacionados que tienen un nombre de contacto concreto. El nombre se determina a su vez en función del usuario que realiza la solicitud. En este ejemplo se supone que el servicio de datos se hospeda dentro de una aplicación web ASP.NET que usa WCF, y que la autenticación está habilitada. La clase HttpContext se usa para recuperar el principio de la solicitud actual.

' Define a query interceptor for the Orders entity set.
<QueryInterceptor("Orders")> _
Public Function OnQueryOrders() As Expression(Of Func(Of Order, Boolean))
    ' Filter the returned orders to only orders 
    ' that belong to a customer that is the current user.
    Return Function(o) o.Customer.ContactName = _
        HttpContext.Current.User.Identity.Name
End Function
// Define a query interceptor for the Orders entity set.
[QueryInterceptor("Orders")]
public Expression<Func<Order, bool>> OnQueryOrders()
{
    // Filter the returned orders to only orders 
    // that belong to a customer that is the current user.
    return o => o.Customer.ContactName ==
        HttpContext.Current.User.Identity.Name;
}

En este ejemplo se define un método interceptor de cambios para el conjunto de entidades Products. Este método valida la entrada al servicio para una operación Add o Change y produce una excepción si se hace un cambio en un producto que ya no se fabrica. También bloquea la eliminación de productos como una operación no admitida.

' Define a change interceptor for the Products entity set.
<ChangeInterceptor("Products")> _
Public Sub OnChangeProducts(ByVal product As Product, _
                            ByVal operations As UpdateOperations)
    If operations = UpdateOperations.Change Then
        Dim entry As System.Data.Objects.ObjectStateEntry

        If Me.CurrentDataSource.ObjectStateManager _
            .TryGetObjectStateEntry(product, entry) Then

            ' Reject changes to a discontinued Product.
            ' Because the update is already made to the entity by the time the 
            ' change interceptor in invoked, check the original value of the Discontinued
            ' property in the state entry and reject the change if 'true'.
            If CType(entry.OriginalValues("Discontinued"), Boolean) Then
                Throw New DataServiceException(400, String.Format(
                            "A discontinued {0} cannot be modified.", product.ToString()))
            Else
                Throw New DataServiceException(String.Format( _
                    "The requested {0} could not be found in the data source.", product.ToString()))
            End If
        ElseIf (operations = UpdateOperations.Delete) Then
            ' Block the delete and instead set the Discontinued flag.
            Throw New DataServiceException(400, _
                "Products cannot be deleted; instead set the Discontinued flag to 'true'")
        End If
    End If
End Sub
// Define a change interceptor for the Products entity set.
[ChangeInterceptor("Products")]
public void OnChangeProducts(Product product, UpdateOperations operations)
{
    if (operations == UpdateOperations.Change)
    {
        System.Data.Objects.ObjectStateEntry entry;

        if (this.CurrentDataSource.ObjectStateManager
            .TryGetObjectStateEntry(product, out entry))
        {
            // Reject changes to a discontinued Product.
            // Because the update is already made to the entity by the time the 
            // change interceptor in invoked, check the original value of the Discontinued
            // property in the state entry and reject the change if 'true'.
            if ((bool)entry.OriginalValues["Discontinued"])
            {
                throw new DataServiceException(400, string.Format(
                            "A discontinued {0} cannot be modified.", product.ToString()));
            }
        }
        else
        {
            throw new DataServiceException(string.Format(
                "The requested {0} could not be found in the data source.", product.ToString()));
        }
    }
    else if (operations == UpdateOperations.Delete)
    {
        // Block the delete and instead set the Discontinued flag.
        throw new DataServiceException(400, 
            "Products cannot be deleted; instead set the Discontinued flag to 'true'"); 
    }
}

Vea también

Tareas

Cómo: Definir una operación de servicio (WCF Data Services)

Otros recursos

Definir WCF Data Services