Dot-Net

如何以聲明方式指定 AddressFilterMode.Any

  • September 11, 2020

AddressFilterMode.Any當您可以為執行相同操作的 WCF 創建擴展行為時,有很多答案表明需要將其添加為程式碼屬性。

如何以AddressFilterMode.Any程式方式指定

創建自定義行為

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>

引用自:https://stackoverflow.com/questions/6877929