Поделиться через


Как перехватить сообщения службы данных (службы WCF Data Services)

Службы WCF Data Services позволяет приложению перехватывать сообщения запросов, что дает возможность добавить в операцию специализированную логику. Для перехвата сообщений используются методы службы данных со специальными атрибутами. Дополнительные сведения см. в разделе Перехватчики (службы WCF Data Services).

В примере этого раздела используется образец службы данных Northwind. Эта служба создается после выполнения действий, описанных в разделе Краткое руководство по службам WCF Data Services.

Определение перехватчика запросов для набора сущностей Orders

  1. Откройте в проекте службы данных Northwind файл Northwind.svc.

  2. На странице кода класса Northwind добавьте следующую инструкцию using (Imports в коде Visual Basic):

    Imports System.Linq.Expressions
    
    using System.Linq.Expressions;
    
  3. Определите в классе Northwind метод операции службы с именем OnQueryOrders, как показано ниже.

    ' 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()
    

Определение перехватчика изменений для набора сущностей Products

  1. Откройте в проекте службы данных Northwind файл Northwind.svc.

  2. Определите в классе Northwind метод операции службы с именем OnChangeProducts, как показано дальше:

    ' 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)
    

Пример

Этот пример определяет метод перехватчика запросов для набора сущностей Orders, который возвращает лямбда-выражение. Это выражение содержит делегат, который фильтрует запрошенный набор сущностей Orders на основе связанных сущностей Customers с определенным именем контакта. Имя в свою очередь определяется в зависимости от вызывающего пользователя. Пример предполагает, что служба данных размещена в веб-приложении ASP.NET, использующем WCF, и что проверка подлинности включена. Класс HttpContext используется для извлечения участника текущего запроса.

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

Этот пример определяет метод перехватчика изменений для набора сущностей Products. Метод проверяет входные данные службы для операции Add или Change и формирует исключение, если изменение производится над отсутствующим продуктом. Кроме того, удаление продуктов блокируется как неподдерживаемая операция.

' 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'"); 
    }
}

См. также

Задачи

Как определить операцию службы (службы WCF Data Services)

Другие ресурсы

Определение службы WCF Data Services