If you WCF service is hosed behind Load balancer or firewall , or been forwarded by any kind of device. you may end with an error like
| The message with To 'http://127.0.0.1:8888/bHost1/WCFService1.svc' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree. |
if you have the source code, you may have to put one attribute to each of those services.
| [ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)] |
that’s fine if you own the source code. or just handful of service. If you have hundreds of service, that will be terrible change. How to do that in that case.
answse is pretty simple, write a behavior and apply it to the configuration. All you have to do is writing a behavior which will change the default addressfilter, and Apply the behavior by changing the web.config or app.config
| using System; using System.Collections.Generic; using System.Text; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using System.ServiceModel.Configuration; namespace Androidyou.TestLib { public class OverrideWCFAddressFilterServiceBehavior : IServiceBehavior { public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++) { ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher; foreach (EndpointDispatcher dispatcher2 in channelDispatcher.Endpoints) { dispatcher2.AddressFilter = new MatchAllMessageFilter(); } } } public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { } } public class OverrideAddressFilterModeElement : BehaviorExtensionElement { public override Type BehaviorType { get { return typeof(OverrideWCFAddressFilterServiceBehavior); } } protected override object CreateBehavior() { return new OverrideWCFAddressFilterServiceBehavior(); } } } |
Config change.
| <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="newbehavior"> <matchalladdressfilter/> </behavior> </serviceBehaviors> </behaviors> <extensions> <behaviorExtensions> <add name="matchalladdressfilter" type="Androidyou.TestLib.OverrideAddressFilterModeElement, Androidyou.TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> <services> <service name="ConsoleApplication4.SayService" behaviorConfiguration="newbehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:9999/svc"/> </baseAddresses> </host> <endpoint address="ws" binding="wsHttpBinding" bindingConfiguration="wsbinding" contract="ConsoleApplication4.SayService" /> </service> </services> </system.serviceModel> </configuration> |
Or you may apply the behavior in Code.
| host.Description.Behaviors.Add(new Androidyou.TestLib.WCFSecurityLib.OverrideWCFAddressFilterServiceBehavior()); |
if you want to change addressfiltermode programmatically, you may put a switch into the above behaviors, like a static variable, then change the switch programmatically which will cause the behavior to refresh the filtermode.