Как перехватить сообщения службы данных (службы WCF Data Services)
Службы WCF Data Services позволяет приложению перехватывать сообщения запросов, что дает возможность добавить в операцию специализированную логику. Для перехвата сообщений используются методы службы данных со специальными атрибутами. Дополнительные сведения см. в разделе Перехватчики (службы WCF Data Services).
В примере этого раздела используется образец службы данных Northwind. Эта служба создается после выполнения действий, описанных в разделе Краткое руководство по службам WCF Data Services.
Определение перехватчика запросов для набора сущностей Orders
Откройте в проекте службы данных Northwind файл Northwind.svc.
На странице кода класса
Northwind
добавьте следующую инструкцию using (Imports в коде Visual Basic):Imports System.Linq.Expressions
using System.Linq.Expressions;
Определите в классе
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
Откройте в проекте службы данных Northwind файл Northwind.svc.
Определите в классе
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)