我正在使用WCF IClientMessageInspector将标头中的信息发送到WCF服务(wsHTTP)。我正在使用IDispatchMessageInspector接收信息并填充String属性。
我验证了标头正在正确发送信息,因为我在我的特定方法中使用了FindHeader,但我宁愿只访问具有Token属性的自定义类并从那里获取Token,而不是在一个中执行FindHeader。所有其他方法调用以获取标头值的单独方法。
所以我的问题是,从服务器端(我假设的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
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
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
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
结束班
答案 0 :(得分:2)
根据模式,我看到WCF团队正在建立,我的建议是让你的IDispatchMessageInspector将标头的值移到当前的OperationContext的IncomingMessageProperties字典中。通过执行此操作,该值将绑定到当前操作上下文,并由WCF运行时为您执行所有执行阶段。
至于如何在堆栈中进一步读取该值,您可以做两件事。首先,您可以公开您将用于读取/写入静态只读字符串上的属性集合的值的字符串键,其他代码可以使用它来从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;