7

ここに2つのクエリがあります:-

1)基本的な違いは何ですかMicrosoft.ServiceModel.Web.RequestInterceptor and System.ServiceModel.Dispatcher.DispatchRuntime.MessageInspectors (IdispatchMessageInterceptor)

どちらも、リクエスト パイプラインにカスタム検証/インターセプターを実装するために使用できるリクエスト/メッセージ インターセプターのようです。

いつ別のものを使用するのですか?

2) また、プラグインRequestInterceptorの方法RouteTable.Routes.Add(new ServiceRoute())

私はこのようなクラスを持っています -

public class AuthenticationInterceptor : RequestInterceptor
{
   //Authentication logic goes here......
}

そして、このようなルート定義: -

RouteTable.Routes.Add(new ServiceRoute(routePrefix, new MyServiceHostFactory(container, (sh) => {
                foreach (System.ServiceModel.Dispatcher.ChannelDispatcher cd in sh.ChannelDispatchers)
                {
                    foreach (System.ServiceModel.Dispatcher.EndpointDispatcher ed in cd.Endpoints)
                    {
                        ed.DispatchRuntime.MessageInspectors.Add(new AuthenticationInterceptor());
                    }
                }
                return sh; })));

の定義は次のMyServiceHostFactoryとおりです。

public MyServiceHostFactory(IocContainer container, Func<ServiceHost, ServiceHost> createservicehost = null);

現在、次のエラーがスローされています: -

The best overloaded method match for 'System.Collections.Generic.SynchronizedCollection<System.ServiceModel.Dispatcher.IDispatchMessageInspector>.Add(System.ServiceModel.Dispatcher.IDispatchMessageInspector)' has some invalid arguments

この行で: -

ed.DispatchRuntime.MessageInspectors.Add(new AuthenticationInterceptor());

MessageInspector で RequestInterceptor を接続しようとしているからです。どちらも異なるインターフェイス階層にあります。

それで、私はここで何をすべきですか?

編集:

また、コードが自分の管理下にないため、AuthenticationInterceptor ロジックを変更できないことにも注意してください。

4

1 に答える 1

10

質問に対する回答は次のとおりです (インターセプターとインスペクターを少し理解するには、ポイント 2 まで読む必要があります)。

1. エラーの解決策(コード ロジックを追加する必要があります)

次のコードで IDispatchMessageInspector を実装します。次のクラスの名前はインスペクターに変更する必要があることに注意してください。ただし、言及したように変更できないため、ここにインターフェイスを実装する必要があります。それ以外の場合は、インスペクターのサフィックスと実装が一致する別のクラスを作成することをお勧めします。

public class AuthenticationInterceptor : RequestInterceptor, IDispatchMessageInspector
{
    //Authentication logic goes here......
    object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
    {
        //Your code here.
    }
    void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        //Your code here.
    }
}

2. RequestInterceptor と MessageInspector の違い

クライアントとサーバーの通信には、2 つの重要な通信フェーズがあります。1 つ目は、クライアントがサーバーとの接続を確立するとき、2 つ目は両方が通信するときです。

接続を確立するとき、接続を確立しようとしているクライアントが有効なクライアントである必要はありません。未承認のリクエストである可能性もあれば、リクエストが有効であるが、宛先のサーバーを対象としていないため、承認または接続の再ルーティングが必要な可能性もあります。

再ルーティングの良い例は次の場合です。

  1. 地域のクライアント/サーバーに地域間の通信を回避させたいが、クライアントの 1 つ (これは有効) が別の地域のサーバーに接続しようとする場合。

  2. 少数の例外的なユーザーにクロスリージョンのクライアント/サーバー通信を許可するかどうかをサーバーで選択的に決定する必要があります。

この回答の範囲外である、さらに複雑な再ルーティングのシナリオが存在する可能性があります。

したがって、WCF では、Rest スターター キットにより、接続確立フェーズで要求をインターセプトする追加機能が提供されます。インターセプター(あなたの場合は AuthenticationInterceptor )はそのようなリクエストを認証する必要があり、リクエストが無効な場合は、必要なエントリをログに記録し、この拒否されたクライアント/セッションからの通信をさらに処理することを拒否できます。

RequestInterceptor を持つことには多くの利点があります。

  1. 非常に早い段階で受信リクエストを検証するのに役立ちます。

  2. カスタムオーセンティケーターを構築したり、コンポーネントを再ルーティングしたりするのに役立ちます。

  3. WCF サービス/サーバーから不要な負荷を遠ざけるために非常に重要な、要求フェーズ自体の間のそれ以降のメッセージ処理をブロックします。

Message Inspectors: MessageInspectors は、Request が検証され、接続が十分に確立されている場合に、クライアント/サーバー通信の第 2 フェーズの一部として扱うことができるため、クライアント/サーバーが相互にメッセージを渡すことによって通信を開始する必要があるときです。ここで、アプリケーション環境では、バイナリ、xml、または json のシリアル化された形式を使用してメッセージが渡される可能性があります。適用可能な暗号化が存在する可能性があります。

たとえば、メッセージがクライアント A から到着し、サーバー B に渡される可能性があります。サーバーは別のサーバー D からの情報を待つことができる別のサーバー C のキューに入れます。サーバー D が情報を提供すると、サーバー Cメッセージをキューに入れ、サーバーBとサーバーDから受信した生のメッセージをさらに結合し、それを別のサービスに渡して逆シリアル化し、サーバーBに返すことができる意味のあるものに変換し、BはそれをクライアントAに返します.

かなり複雑ですよね?ただし、モバイル PIN を使用したクレジット カードによる支払いのようなマルチ サーバー認証は、まったく同じではなく、さらに複雑な場合もありますが、同様の方法で機能します。

WCF では、インターセプターとインスペクターは連携して作業できますが、それぞれの役割は異なります。インターセプターはエンド ユーザー/接続/再ルーティングを検証し、インスペクターはメッセージを検証/処理します。

いくつかのポイント:

  1. クライアント側に IClientMessageInspector を実装し、サーバー側に IDispatchMessageInspector を実装することで、独自のメッセージ インスペクターを構築できます。

  2. クライアント コンポーネントとサーバー コンポーネントの両方の所有者であれば、両方のインターフェイスを 1 つのクラスに実装できます。

  3. ここで、あなたの場合、IDispatchMessageInspector を実装する必要があるようです。

IDispatchMessageInspector を実装するクラスは、前述のようにインターセプトしませんが、受信メッセージと送信メッセージを「検査」することを目的としています。このインスペクターは、メッセージがクライアントから到着したときに、構成を使用してフックできます。

この時点までに、インスペクター レベルでは、到着したメッセージは既にさまざまなチャネル スタック レベルで処理され、この要求を処理する WCF サービスに割り当てられていることに注意してください。間に暗号化を使用している場合、メッセージは既に復号化されています。ただし、メッセージはまだデシリアライズされていません。

カスタム インスペクターを使用すると、システムが (銀行の SWIFT/FIX プロトコル) や別のレベルの zip/unzip エンコーディングなどのカスタム シリアル化形式を実装できる可能性があります。

このカスタム インスペクターは、データを逆シリアル化し、逆シリアル化されたデータで実際に動作するコンポーネント COMP に渡すことができます。

IDispatchMessageInspector インターフェイスには、実装する必要がある 2 つのメソッドがあります。

a) AfterReceiveRequest および

b) BeforeSendReply(ref メッセージ、オブジェクト)。

AfterReceiveRequest は、データを逆シリアル化して COMP に渡すメソッドであり、BeforeSendReply は、データを再度シリアル化し、メッセージに対して任意の操作を実行するメソッドです。

ビヘイビアーを使用して、Web サービスが受信するすべてのメッセージに MessageInspector を添付できます。カスタム インターセプターとインスペクターはどちらも、エンタープライズ プラットフォームまたは高度にカスタマイズ可能なプラットフォームで使用することを主な目的としています。

この回答がお役に立てば幸いです。次のリンクで詳細を読むことができます (最初のリンクを通過している可能性があります)。

http://msdn.microsoft.com/en-us/library/ee391967.aspx

http://msdn.microsoft.com/en-us/library/aa717047(v=vs.110).aspx

よろしくカジャル

于 2014-06-28T19:47:42.053 に答える