如何访问用于在WCF服务(服务器端)上实现IDispatchMessageInspector的类中的属性? [英] How to access a property in a class used to implement IDispatchMessageInspector on a WCF service (server side)?

查看:92
本文介绍了如何访问用于在WCF服务(服务器端)上实现IDispatchMessageInspector的类中的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用WCF IClientMessageInspector将标头中的信息发送到WCF服务(wsHTTP).我正在使用IDispatchMessageInspector接收信息并填充String属性.

I am using the WCF IClientMessageInspector to send information in a header to a WCF service (wsHTTP). I am using the IDispatchMessageInspector to receive the information and populate a String property.

我验证了标头在我在特定方法中使用FindHeader时正确发送了信息,但我宁愿只访问具有Token属性并从那里获取Token的自定义类,而不必在所有其他方法都调用以获取标头值的单独方法.

I verified the header is sending the information properly as I use the FindHeader within my specific method but I'd rather just access the custom class that has the Token property and GET the Token from there rather than having to do FindHeader in a separate method that all other methods call to get the header value.

所以我的问题是,从服务器端(我认为是OperationContext),如何访问具有Token属性并填充了标头信息的此类实例?

So my question is, from the server side (OperationContext I presume) how do I access this class instance that has the Token property populated with the header info?

这是下面整个类的代码:

Here is the code from the entire class below:

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

结束区域

结束班级

推荐答案

基于我看到他们建立的WCF团队的模式,我的建议是让您的IDispatchMessageInspector将标头的值推入当前OperationContext的 IncomingMessageProperties 字典.这样,该值将与当前操作上下文相关联,并由WCF运行时为您正确执行所有执行阶段.

Based on patterns I see the WCF team themsevles establishing, my suggestion would be to have your IDispatchMessageInspector shove the value of the header into the current OperationContext's IncomingMessageProperties dictionary. By doing this, the value will be tied to the current operation context and carried through all stages of execution properly for you by the WCF runtime.

至于如何从堆栈中进一步读取该值,您可以做两件事.首先,您可以将用于将值读/写到静态只读字符串上的属性集合的字符串键公开给其他代码可以在其中使用的字符串,以便其他代码可以从OperationContext中检索值.Current本身就像这样:

As far as how to read that value further down the stack out you can do two things. First, you can expose the string key you will be using to read/write the value to the properties collection on a static readonly string somewhere that other code can use it to retrieve the value from the OperationContext.Current themselves like so:

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

现在,这仍然需要所有需要读取值的人进行很多编码.获取当前上下文,使用键索引到字典中并将结果转换为正确的类型(我在上面将int用作示例).如果您想花哨的话,可以采取的下一步操作是通过自己的上下文类公开这些属性,以便人们可以像常规的强类型CLR属性一样访问它们.可能看起来像这样:

Now, this still requires a lot of coding on the part of all the people who need to read the value. Getting the current context, indexing into the dictionary with the key and casting the result to the proper type (I used int as a sample above). If you want to get fancy, the next step you can take is to instead just expose these properties via your own context class so people can just access them like normal, strongly typed CLR properties. That might look a little something like this:

首先,在名为MyOperationContext的类上实现静态访问​​器属性:

First, implement a static accessor property on a class called MyOperationContext:

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

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

现在,在需要读取此标头的各种实现中,他们只需执行以下操作即可:

Now in your various implementations that need to read this header they would simply do:

int value = MyOperationContext.MyHeader;

这篇关于如何访问用于在WCF服务(服务器端)上实现IDispatchMessageInspector的类中的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆