다음을 통해 공유


방법: 데이터 서비스 메시지 가로채기(WCF Data Services)

WCF Data Services 를 사용하면 사용자 지정 논리를 작업에 추가할 수 있도록 요청 메시지를 가로챌 수 있습니다. 메시지를 가로채려면 데이터 서비스에서 특별한 특성이 있는 메서드를 사용합니다. 자세한 내용은 인터셉터(WCF Data Services)를 참조하십시오.

이 항목의 예제에서는 Northwind 샘플 데이터 서비스를 사용합니다. 이 서비스는 WCF Data Services 퀵 스타트를 완료하면 만들어집니다.

Orders 엔터티 집합에 대해 쿼리 인터셉터를 정의하려면

  1. Northwind 데이터 서비스 프로젝트에서 Northwind.svc 파일을 엽니다.

  2. Northwind 클래스의 코드 페이지에서 다음 using 문(Visual Basic에서는 Imports)을 추가합니다.

    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 엔터티 집합에 대해 람다 식을 반환하는 쿼리 인터셉터 메서드를 정의합니다. 이 식에는 특정 연락처 이름이 있는 관련 Customers를 기반으로 요청된 Orders를 필터링하는 대리자가 포함되어 있습니다. 이름은 요청하는 사용자를 기반으로 확인됩니다. 이 예제에서는 WCF를 사용하고 인증이 사용하도록 설정된 ASP.NET 웹 응용 프로그램 내에 데이터 서비스가 호스팅된다고 가정합니다. 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 정의