这个问题似乎被问过很多次,但我就是无法让它工作。
首先,我现在已经在Windows 7和Windows 8上使用VS 2012尝试了此操作,并且遇到了完全相同的问题。
我正在尝试编写一个接收和处理 SOAP 标头消息的 WCF 服务,经过大量搜索后发现我应该使用消息拦截器来读取和处理 SOAP 标头。
因此,我在本地计算机上创建了一个新网站,并将其命名为DemoMessageInspector。在此解决方案中,我添加了以下类:
HmacVerificationBehavior
Imports System.ServiceModel.Description
Public Class HmacVerificationBehavior
Implements IEndpointBehavior
#Region "IEndpointBehavior Members"
Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
End Sub
Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
Dim inspector As New HmacVerificationInspector()
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)
End Sub
Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
End Sub
#End Region
End Class
Hmac验证配置部分
Imports System.ServiceModel.Configuration
Imports System.ServiceModel.Description
Namespace NamespaceHere
Public Class HmacVerificationConfigurationSection
Inherits BehaviorExtensionElement
Implements IServiceBehavior
#Region "IServiceBehavior Members"
Public Sub AddBindingParameters(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase, endpoints As System.Collections.ObjectModel.Collection(Of ServiceEndpoint), bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IServiceBehavior.AddBindingParameters
End Sub
Public Sub ApplyDispatchBehavior(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements IServiceBehavior.ApplyDispatchBehavior
End Sub
Public Sub Validate(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements IServiceBehavior.Validate
End Sub
#End Region
Public Overrides ReadOnly Property BehaviorType() As Type
Get
Return GetType(HmacVerificationBehavior)
End Get
End Property
Protected Overrides Function CreateBehavior() As Object
Return New HmacVerificationBehavior()
End Function
End Class
End Namespace
HmacVerificationInspector
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Public Class HmacVerificationInspector
Implements IDispatchMessageInspector
#Region "IDispatchMessageInspector Members"
Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, channel As System.ServiceModel.IClientChannel, instanceContext As System.ServiceModel.InstanceContext) As Object
Dim buffer As MessageBuffer = request.CreateBufferedCopy(Int32.MaxValue)
request = buffer.CreateMessage()
Dim dupeRequest As Message = buffer.CreateMessage()
ValidateHmac(dupeRequest)
buffer.Close()
Return Nothing
End Function
Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message, correlationState As Object)
End Sub
#End Region
Public Function AfterReceiveRequest1(ByRef request As Message, channel As ServiceModel.IClientChannel, instanceContext As ServiceModel.InstanceContext) As Object Implements IDispatchMessageInspector.AfterReceiveRequest
End Function
Public Sub BeforeSendReply1(ByRef reply As Message, correlationState As Object) Implements IDispatchMessageInspector.BeforeSendReply
End Sub
End Class
服务对象
Imports System.ServiceModel
' NOTE: You can use the "Rename" command on the context menu to change the interface name "IService" in both code and config file together.'
<ServiceContract()>
Public Interface IService
<OperationContract()>
Sub DoWork()
<OperationContract()>
Function DoSomething(ByVal _str As String) As String
End Interface
和服务
Public Class Service
Implements IService
Public Sub DoWork() Implements IService.DoWork
End Sub
Public Function DoSomething(ByVal _str As String) As String Implements IService.DoSomething
Return "Message [" & _str & "]"
End Function
End
Web.Config 文件如下所示:
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="hmacVerification"
type="NamespaceHere.HmacVerificationConfigurationSection, NamespaceHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<services>
<service name="MySecureService">
<endpoint address="" binding="webHttpBinding" contract="IMySecureService" behaviorConfiguration="web"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp automaticFormatSelectionEnabled="true"/>
<hmacVerification /> *********COMMENT OUT**************
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>
因此,我们有示例代码,如果在 Web.config 中注释掉该行,则可以完美运行。取消注释后,将发生以下情况:
Server Error in '/DemoMessageInspector' Application.
--------------------------------------------------------------------------------
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: The type 'NamespaceHere.HmacVerificationConfigurationSection, NamespaceHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' registered for extension 'hmacVerification' could not be loaded.
Source Error:
Line 25: <behavior name="web">
Line 26: <webHttp automaticFormatSelectionEnabled="true"/>
Line 27: <hmacVerification />
Line 28: </behavior>
Line 29: </endpointBehaviors>
Source File: C:inetpubwwwrootDemoMessageInspectorweb.config Line: 27
--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18044
所以,问题基本上是应该如何配置?
或者,也许问题是,这是用于完成从 WCF 终结点读取 SOAP 标头等简单任务的正确方法吗?
如果您需要做的就是"完成一个简单的任务,即从 WCF 终结点读取 SOAP 标头",那么您应该能够使用:
OperationContext.Current.IncomingMessageHeaders
以下链接包含传入消息标头集合的实现详细信息:
http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.incomingmessageheaders.aspx