WCF:如何以声明方式指定AddressFilterMode.Any

时间:2011-07-29 19:15:37

标签: .net wcf

我提前为回答我自己的问题而道歉但是我看到很多答案,说明当你可以为WCF创建同样的东西时,需要将AddressFilterMode.Any添加为代码属性。在很多地方提出同样的问题,我认为在一个地方回答这个问题会更有益。

2 个答案:

答案 0 :(得分:4)

创建自定义行为

Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels

'We're assuming your project declares some default namespace like Org.ServiceModel
Namespace Description
Public Class AddressFilterModeAnyBehavior
    Implements IEndpointBehavior

    Private Const jsPostfix As String = "js"
    Private Const jsdebugPostFix As String = "jsdebug"

    Private Const MaxMetadataEndpointBufferSize As Integer = 2048

    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

    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
        If endpointDispatcher Is Nothing Then Return
        endpointDispatcher.AddressFilter = New MatchAllMessageFilter
        If (HasWebScriptBehavior(endpoint)) Then
            HandleWebScriptBehavior(endpoint, endpointDispatcher)
        End If
    End Sub

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

    End Sub

    Protected Sub HandleWebScriptBehavior(ByVal endpoint As ServiceEndpoint, ByVal endpointDispatcher As EndpointDispatcher)
        If endpoint Is Nothing OrElse endpointDispatcher Is Nothing Then Exit Sub
        If Not HasListenUri(endpoint) Then Exit Sub
        Dim baseAddress As Uri = endpoint.Address.Uri
        Dim jsUri As Uri = CreateWebScriptUri(baseAddress, False)
        Dim jsdebugUri As Uri = CreateWebScriptUri(baseAddress, True)
        Dim host As ServiceHostBase = endpointDispatcher.ChannelDispatcher.Host
        Dim channelDispatchers As ChannelDispatcherCollection = host.ChannelDispatchers
        For Each channelDispatcher As ChannelDispatcher In channelDispatchers
            For Each dispatcher As EndpointDispatcher In channelDispatcher.Endpoints
                With dispatcher
                    Dim endpointUri As Uri = .EndpointAddress.Uri
                    If (endpointUri.Equals(jsdebugUri) OrElse endpointUri.Equals(jsUri)) Then
                        .AddressFilter = New MatchAllMessageFilter
                    End If
                End With
            Next
        Next
    End Sub

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")>
    Protected Function HasWebScriptBehavior(ByVal endpoint As ServiceEndpoint) As Boolean
        If endpoint Is Nothing Then Return False
        Return (From behavior In endpoint.Behaviors Where TypeOf behavior Is WebScriptEnablingBehavior).Any
    End Function

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")>
    Protected Function HasListenUri(ByVal endpoint As ServiceEndpoint) As Boolean
        If endpoint Is Nothing Then Return False
        Return Not endpoint.Address.Uri.Equals(endpoint.ListenUri)
    End Function

    <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")>
    Protected Function CreateWebScriptUri(ByVal baseUri As Uri, ByVal debug As Boolean) As Uri
        Dim builder As New UriBuilder(baseUri)
        If (debug) Then
            builder.Path += If(builder.Path.EndsWith("/", StringComparison.OrdinalIgnoreCase), (jsdebugPostFix), ("/" + jsdebugPostFix))
        Else
            builder.Path += If(builder.Path.EndsWith("/", StringComparison.OrdinalIgnoreCase), (jsPostfix), ("/" + jsPostfix))
        End If
        Return builder.Uri
    End Function


End Class
End Namespace

创建自定义配置元素

Imports System.ServiceModel
Imports System.ServiceModel.Configuration
Imports Hsb.ServiceModel.Description

'We're assuming your project declares some default namespace like Org.ServiceModel
Namespace Configuration

Public Class AddressFilterModeAnyElement
    Inherits BehaviorExtensionElement


#Region "BehaviorExtensionElement Implementation"
    'The BehaviorExtensionElement base class allows the behavior to be added through configuration
    'using the system.servicemodel/extensions .config element.
    <System.Diagnostics.CodeAnalysis.SuppressMessage("Configuration", "Configuration102:ConfigurationPropertyAttributeRule", MessageId:="System.ServiceModel.Configuration.WebScriptEnablingElement.BehaviorType", Justification:="Not a configurable property; a property that had to be overridden from abstract parent class")> _
    Public Overrides ReadOnly Property BehaviorType() As System.Type
        Get
            Return GetType(AddressFilterModeAnyBehavior)
        End Get
    End Property

    Protected Overrides Function CreateBehavior() As Object
        Return New AddressFilterModeAnyBehavior()
    End Function
#End Region

End Class
End Namespace

在WCF配置中使用扩展元素 我们假设程序集名为Org.ServiceModel

<system.serviceModel>
 <behaviors>
  <endpointBehaviors>
    <behavior name="JSON">          
      <enableWebScript />
      <addressFilterModeAny />
    </behavior>        
  </endpointBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <!-- Microsoft Connect Issue ID 216431: The full assembly qualified typename including version, culture and key must be specified.-->
    <!-- The following endpoint behavior extension element sets the endpoint's address filter mode to any.  This allows the service
    to operate behind an SSL load balancer where externally https is used and internally http is used.-->
    <add name="addressFilterModeAny" type="Org.ServiceModel.Configuration.AddressFilterModeAnyElement, Org.ServiceModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>
</system.serviceModel>

答案 1 :(得分:0)

如果要在创建服务主机时在代码中指定它:

host.Description.Behaviors.Find<ServiceBehaviorAttribute>().AddressFilterMode = AddressFilterMode.Any;

host.Description.Behaviors.Add(new ServiceBehaviorAttribute { AddressFilterMode = AddressFilterMode.Any });

取决于您的服务是否已有ServiceBehaviorAttribute