WCF消息交叉点配置问题

时间:2013-09-30 10:45:18

标签: .net web-services wcf soap idispatchmessageinspector

这个问题似乎已被多次询问,但我无法让它发挥作用。

首先,我现在已经在Windows 7和Windows 8上使用VS 2012在两者上尝试了这个并且具有完全相同的问题。

我正在尝试编写一个接收和处理SOAP头消息的WCF服务,经过大量搜索后发现我应该使用Message Interceptor来读取和处理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

HmacVerificationConfigurationSection

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

IService

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:\inetpub\wwwroot\DemoMessageInspector\web.config    Line:  27 


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18044 

那么,问题基本上应该如何配置呢?

或许问题是,这是否是用于完成从WCF端点读取SOAP标头的简单任务的正确方法?

1 个答案:

答案 0 :(得分:2)

如果您只需要“完成从WCF端点读取SOAP标头的简单任务”,那么您应该可以使用:

OperationContext.Current.IncomingMessageHeaders

以下链接包含IncomingMessageHeaders集合的实现详细信息:

http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.incomingmessageheaders.aspx