次の方法で共有


方法: データ サービス メッセージを先に取得する (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 エンティティ セットのクエリ インターセプター メソッドを定義します。 この式には、要求された Orders を特定の連絡先名が付けられた関連 Customers に基づいてフィルターするデリゲートが含まれます。 この名前は、要求ユーザーに基づいて決定されます。 この例では、認証が有効化され、WCF を使用する ASP.NET Web アプリケーション内でデータ サービスがホストされていることを前提とします。 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 の定義