0

WCF IClientMessageInspector を使用して、ヘッダー内の情報を WCF サービス (wsHTTP) に送信しています。IDispatchMessageInspector を使用して情報を受け取り、String プロパティを設定しています。

特定のメソッド内で FindHeader を使用しているため、ヘッダーが情報を適切に送信していることを確認しましたが、別のメソッドで FindHeader を実行するのではなく、Token プロパティを持つカスタム クラスにアクセスし、そこからトークンを取得したいだけです。他のすべてのメソッドは、ヘッダー値を取得するために呼び出します。

私の質問は、サーバー側 (OperationContext だと思います) から、ヘッダー情報が入力された Token プロパティを持つこのクラス インスタンスにアクセスするにはどうすればよいですか?

以下は、クラス全体のコードです。

地域「輸入」

Imports System.ServiceModel
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Description
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Configuration

エンドリージョン

Public Class MessageInspector
    Inherits BehaviorExtensionElement
    Implements IClientMessageInspector, IDispatchMessageInspector, IEndpointBehavior

    Private Const headerName As String = "HeaderToken"
    Private Const headerNamespace As String = "urn:com.nc-software.services:v1"

    Private _token As String
    Public Property Token() As String
        Get
            Return _token
        End Get
        Set(ByVal Value As String)
            _token = Value
        End Set
    End Property

    Public Overrides ReadOnly Property BehaviorType() As System.Type
        Get
            Return GetType(MessageInspector)
        End Get
    End Property

    Protected Overrides Function CreateBehavior() As Object
        Return New MessageInspector
    End Function

領域 " IEndpointBehavior "

Public Sub AddBindingParameters(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters
End Sub

Public Sub ApplyClientBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) Implements System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior
    clientRuntime.MessageInspectors.Add(Me)
End Sub

Public Sub ApplyDispatchBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior
    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(Me)
End Sub

Public Sub Validate(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint) Implements System.ServiceModel.Description.IEndpointBehavior.Validate
End Sub

エンドリージョン

領域「 IClientMessageInspector 」

Public Sub AfterReceiveReply(ByRef reply As System.ServiceModel.Channels.Message, ByVal correlationState As Object) Implements System.ServiceModel.Dispatcher.IClientMessageInspector.AfterReceiveReply
End Sub

Public Function BeforeSendRequest(ByRef request As System.ServiceModel.Channels.Message, ByVal channel As System.ServiceModel.IClientChannel) As Object Implements System.ServiceModel.Dispatcher.IClientMessageInspector.BeforeSendRequest
    Dim header As New MessageHeader(Of String)(Token)
    Dim untypedHeader As MessageHeader = header.GetUntypedHeader(headerName, headerNamespace)
    request.Headers.Add(untypedHeader)
    Return Nothing
End Function

エンドリージョン

領域「 IDispatchMessageInspector 」

Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, ByVal channel As System.ServiceModel.IClientChannel, ByVal instanceContext As System.ServiceModel.InstanceContext) As Object Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.AfterReceiveRequest
    Try
        Dim headers As MessageHeaders = OperationContext.Current.IncomingMessageHeaders
        Dim headerIndex As Integer = headers.FindHeader(headerName, headerNamespace)
        If headerIndex >= 0 Then
            Token = headers.GetHeader(Of String)(headerIndex)
        End If
    Catch
    End Try
    Return Nothing
End Function

Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message, ByVal correlationState As Object) Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply
End Sub

エンドリージョン

クラス終了

4

1 に答える 1

2

WCF チームが確立しているパターンに基づいて、IDispatchMessageInspector でヘッダーの値を現在の OperationContext のIncomingMessagePropertiesディクショナリに押し込むことをお勧めします。これにより、値は現在の操作コンテキストに関連付けられ、WCF ランタイムによって実行のすべての段階で適切に実行されます。

その値をスタックのさらに下に読み取る方法に関しては、2 つのことができます。まず、値の読み取り/書き込みに使用する文字列キーを、静的な読み取り専用文字列のプロパティ コレクションに公開し、他のコードがそれを使用して OperationContext.Current 自体から値を取得できるようにします。

int value = (int)OperationContext.Current.IncomingMessageProperties[MyMessageProperty.MyHeader];

さて、これには、値を読み取る必要があるすべての人々の側で、まだ多くのコーディングが必要です。現在のコンテキストを取得し、キーを使用して辞書にインデックスを付け、結果を適切な型にキャストします (上記の例では int を使用しました)。より凝ったものにしたい場合は、次のステップとして、これらのプロパティを独自のコンテキスト クラスを介して公開するだけで、通常の厳密に型指定された CLR プロパティのようにアクセスできるようになります。それは次のように少し見えるかもしれません:

まず、MyOperationContext というクラスに静的アクセサー プロパティを実装します。

public static int MyHeader
{
    get
    {
        return (int)OperationContext.Current.IncomingMessageProperties[MyMessageProperty.MyMessageProperty];
    }

    set
    {
        OperationContext.Current.IncomingMessageProperties[MyMessageProperty.MyMessageProperty] = value;
    }
}

このヘッダーを読み取る必要があるさまざまな実装では、次のようにするだけです。

int value = MyOperationContext.MyHeader;
于 2010-03-29T17:37:57.660 に答える