5


私の WCF プロジェクトでは、応答でカスタム ヘッダーを使用する必要があるため、IDispatchMessageInspector を実装しました。正直なところ、すべて問題なく動作しますが、ちょっと気になる点が 1 つあります。
問題は、.svc をページとして開いたり、サービスを WCF テスト クライアントにロードしたりしても、BeforeSendReply と AfterReceiveRequest の両方が起動することです。
では、最初の質問: その行動は正常ですか? それを宣言的に処理する方法はありますか (おそらく web.config のトリック)?
現在、次のコードを使用しています:

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        if (reply.Properties.Any(x => x.Key == "httpResponse"))
            return;

        MessageHeader header = MessageHeader.CreateHeader("Success", "NS", !reply.IsFault);
        reply.Headers.Add(header);          
    }

だから今、私はそれを使ってサービス呼び出しではないすべての呼び出しを処理します:

if (reply.Properties.Any(x => x.Key == "httpResponse"))
    return;

しかし、その問題を処理するための他のより良い方法があると確信しています。だから私の主な質問:説明された状況を処理するためのより良い方法を提案してください。
前もって感謝します!

更新 1
私の system.serviceModel セクション

<system.serviceModel>       
    <services>          
        <service behaviorConfiguration="someBehavior" name="serviceName">
            <endpoint address="" binding="basicHttpBinding" contract="my contract" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>     
    <behaviors>
        <serviceBehaviors>              
            <behavior name="someBehavior">
                <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>                  
                <serviceDebug includeExceptionDetailInFaults="false"/>
                <exceptionInspector/>                   
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <extensions>
        <behaviorExtensions>
            <add name="exceptionInspector" type="class which implements BehaviorExtensionElement" />
        </behaviorExtensions>
    </extensions>

</system.serviceModel>

更新 2 (
受け入れられた解決策) 問題の原因を調査するのに時間を費やしましたが、最終的に解決策として受け入れられることがわかりました。
だから私が見つけたもの:
まず第一にMessage、抽象クラスです。そのBeforeSendReplyため、毎回さまざまな種類の具体的なメッセージを受け取ります。 1) - クライアントが svc をページとして開くことを意味します
。結果 = svc サービスに関する一般的な情報を含む、よく知られている HTML 形式のページ。このタイプは. 2) メタデータ リクエストを取得します。これは少しトリッキーな部分で、MEX を使用するかどうかによって異なります。したがって、MEX を使用すると、リクエストは .svc/mex エンドポイントに対して実行され、そのメッセージ タイプはと等しくなります。
System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.MetadataOnHelpPageMessagereply.Version.EnvelopeEnvelopeVersion.None
System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessagereply.Version.EnvelopeEnvelopeVersion.Soap12
MEX を使用しない場合、クライアントは wsdl データを取得するためのリクエストをほとんど実行しません。メッセージの種類は になりますXMLSchemaMessage
3) Web メソッドリクエストを実行します。これは、私のタイプのリクエストにのみ役立ちます。でありSystem.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessagereply.Version.Envelope等しいEnvelopeVersion.Soap11です。

私はbasicHttpBindingを使っているので、SOAPのバージョンは1.1です。したがって、私の最終的なコードは、返信に SOAP エンベロープが含まれていることを確認し、そのバージョンを確認するだけです。エンベロープが存在し、バージョンが 1.1 の場合、Web メソッド呼び出しがあり、カスタム ヘッダーが追加されている可能性があります。

        public void BeforeSendReply(ref Message reply, object correlationState)
    {   
        if(reply.Version.Envelope == EnvelopeVersion.Soap11)
        {               
            MessageHeader header = MessageHeader.CreateHeader("Success", "NS", !reply.IsFault);
            reply.Headers.Add(header);          
        }
    }
4

1 に答える 1

2

同じエンドポイントで公開される、メタデータ (WSDL) への HTTP 要求を含むすべてのメッセージに対して IDispatchMessageInspector が実行されることを覚えているようです。インスペクターの登録方法については言及していないため、それも関連している可能性があります。

それを確認する以外に、メッセージの内容を確認してみましたか? たとえば、サービス HTML ページを含むメッセージには、MessageVersion == MessageVersion.None が含まれる可能性があります。同様に、メッセージに関連付けられたアクションも役立つ場合があります。

于 2011-01-20T16:33:39.387 に答える