1

各リクエストの開始時にいくつかのヘッダー値を抽出し、それらをMEFによってアプリケーションコードに挿入できるClientContextオブジェクトに配置する必要があります。WCF Web APIのプレビュー5を使用していますが、これを行う方法がわかりません。

「標準」のWCFでは、IExtension <OperationContext>を実装するクラスを作成し、次のプロパティを使用してすべてを相互に接続します。

[Export(typeof(IClientContext)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public static ClientContextExtension Current
{
    get
    {
        var operationContext = OperationContext.Current;

        if (operationContext == null)
            return null;

        var extension = operationContext.Extensions.Find<ClientContextExtension>();

        if (extension == null)
        {
            extension = new ClientContextExtension();

            operationContext.Extensions.Add(extension);
        }

        return extension;
    }
}

カスタムDelegatingHandlerはClientContextExtension.Currentを呼び出し、ヘッダー値からプロパティを設定します。残念ながら、WCF Web APIでは、OperationContext.Currentは常にnullです。

これをWebAPIで機能させる方法がわかりません。どんな助けでも大歓迎です!!!

4

2 に答える 2

1

私は実用的な解決策を考え出しましたが、他の選択肢を受け入れ続けています。まず、元のアプローチの背後にあるいくつかの理論的根拠...

WCFはスレッドプーリングを使用するため、スレッドごとのモデルに基づくものはすべて、個々の要求を超えて存続する可能性があります(そしてそうなるでしょう)。情報は毎回異なるため、リクエストごとにHTTPヘッダーから取得したクライアントコンテキスト情報を保存する方法が必要でした。これは、スレッドが再利用されるため、スレッドごとにコンテキスト情報を保持できないことを意味します。

または私はできますか?

私のロジックの欠陥は、スレッドの再利用が問題だったということでした。実際には、各スレッドは一度に1つのリクエストを処理するだけであり、それによってそのスレッド内の情報はそのリクエストに分離されます。したがって、私がする必要があるのは、情報がその要求に関連していて、私の問題が解決されていることを確認することだけです。

私の解決策は、Currentプロパティをリファクタリングして、[ThreadStatic()]属性でマークされたプライベート静的フィールドを参照し、各インスタンスがスレッドに固有であることを確認することでした。次に、リクエストごとに実行されるDelegatingHandlerで、そのリクエストのオブジェクトのプロパティをリセットします。そのリクエスト中にCurrentを呼び出すと、リクエスト固有の情報が返され、スレッドによって処理される次のリクエストは、他のコードに関する限り、DelegatingHandlerで更新されます。コンテキストはリクエストごとです。

完璧ではありませんが、少なくとも今のところは稼働しています。私が言ったように、私は他の解決策を受け入れています。

アップデート

よく調べてみると、DelegatingHandlerとコンテキストオブジェクトを使用しているサービスコードの間にスレッドアフィニティがないため、このソリューションは機能していません。その結果、ThreadStaticオブジェクトを取得するための呼び出しが期待どおりに機能する場合もありますが、コードがハンドラーとは異なるスレッドで動作しているために、新しいインスタンスを取得する場合もあります。

したがって、このソリューションは無視してください。ふりだしに戻る。

私の更新への更新

Glenn Blockと私の問題について話し合った後、リクエストハンドラー(サービス)が実行しているのと同じスレッドにコンテキストが設定されていることを確認するだけの問題であることがわかりました。解決策は、MessageHandlerの代わりにHttpOperationHandlerを使用することです。

Glennによると、メッセージハンドラーは非同期で動作します。つまり、リクエストハンドラー(サービス)とは異なるスレッドで実行できるため、スレッドアフィニティを必要とするメッセージハンドラーでは何も実行しないでください。一方、操作ハンドラーは要求ハンドラーと同じスレッドで同期的に実行されるため、スレッドアフィニティに依存できます。

そのため、コードをMessageHandlerからHttpOperationHandlerに移動するだけで、目的の結果が得られます。

ここで完全な説明を読むことができます:http ://sonofpirate.blogspot.com/2011/11/modeling-client-context-in-wcf-web-api.html

于 2011-11-16T13:23:13.073 に答える
0

あなたは使用を試みることができます

HttpOperationHandler<HttpRequestMessage, HttpRequestMessage>

そこで、ヘッダーにアクセスできるはずです。

于 2011-11-11T18:36:28.087 に答える