Tuesday, September 14, 2010

Fix WCF AddressFilter mismatch error, customized IServiceBehavior , WCF service behind Load balancer or Firewall

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.

6 comments:

Unknown said...

I added your code to my project and made the changes in the web.config file as instructed but i keep getting the following error.



Parser Error Message: The type 'Androidyou.TestLib.OverrideAddressFilterModeElement, Androidyou.TestLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' registered for extension 'matchalladdressfilter' could not be loaded.

Ryan said...

@Rahul,

Make sure change the Assembly Name

here,
'Androidyou.TestLib.OverrideAddressFilterModeElement, Androidyou.TestLib

using the formatof
[full class name wth namespace],[assembly name]

Androidyou.TestLib is my assembly name, change with yours assemly name, so do the namespace.

Unknown said...

Thanks that worked, but i get a no matching service found in the metadata error now

Anonymous said...

Thanks! Added the attribute...problem went away :-)

Unknown said...

Hi. I've been getting the same error acceding to a WCF service. In my case, I can not modify the service beause it belongs to a third party manufacturer, I solved the issue putting the same port in my local reference. I was redirecting the calls in a DMZ and natting ports. If you change the port, you get the same error:

The message with To 'http://zzzz.zzzz.com:XXXX/MyService/ServiceX' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

I just put on DMZ redirection the same port that is used by the service. This is

PublicDNS:Port222 --> IPDMZ:Port222 --> BackEnd:Port222

Keeping the same port it Works. If you use different ports it fails.

Regards

vdha said...

Hi,

Can you tell me what is the Assembly name that needs to be given here



Is it the assembly name of the bizTalk application??

Can anybody please help me with this. Getting really stuck with the issue.

 
Locations of visitors to this page