I remember running into this many years ago and solving it a bit differently, namely with a behavior. Consider the following:
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.Xml;
internal class CrossDomainServiceBehavior : BehaviorExtensionElement, IEndpointBehavior
{
private ServiceHost serviceHost;
public override Type BehaviorType
{
get { return typeof(CrossDomainServiceBehavior); }
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
if (serviceHost == null)
{
serviceHost = new ServiceHost(typeof(CrossDomainPolicyService));
string address = new Uri(endpoint.Address.Uri, "/").ToString();
ServiceEndpoint crossDomainEndpoint = serviceHost.AddServiceEndpoint(typeof(ICrossDomainPolicyService), new WebHttpBinding(), address);
crossDomainEndpoint.Behaviors.Add(new WebHttpBehavior());
serviceHost.Open();
}
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
protected override object CreateBehavior()
{
return new CrossDomainServiceBehavior();
}
}
internal class CrossDomainPolicyService : ICrossDomainPolicyService
{
public Message ProvideClientAccessPolicyFile()
{
XmlReader xmlReader = CreateClientAccessXml();
return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
}
public Message ProvideCrossDomainPolicyFile()
{
XmlReader xmlReader = CreateCrossDomainXml();
return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
}
private static XmlReader CreateClientAccessXml()
{
TextReader reader = new StringReader(@"<?xml version='1.0' encoding='utf-8'?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers='*' >
<domain uri='*'/>
</allow-from>
<grant-to>
<resource path='/' include-subpaths='true'/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>");
return XmlReader.Create(reader);
}
private static XmlReader CreateCrossDomainXml()
{
TextReader reader = new StringReader(@"<?xml version='1.0'?>
<cross-domain-policy>
<allow-http-request-headers-from domain='*' headers='*'/>
</cross-domain-policy>");
return XmlReader.Create(reader);
}
}
The CrossDomainServiceBehavior needs to be added to the behaviors on your WCF service and it uses the CrossDomainPolicyService for dynamically adding the cross domain policy. This prevents you from having to add the cross domain file to the website itself.
Adding the behavior from code (for example with self hosted services):
endPoint.Behaviors.Add(new CrossDomainServiceBehavior());
Or in case of WCF definitions in config:
For the sake of this example I will assume the CrossDomainServiceBehavior is in the namespace Services.CrossDomainServiceBehavior and the assembly it is located in is version 1.0.0.0 with a neutral culture. It also assumes you have a binding on your service declaration called webHttp.
Registering the behavior:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="CrossDomainServiceBehavior" type="Services.CrossDomainServiceBehavior, CrossDomainServiceBehavior.AssemblyName, Version=1.0.0.0, Culture=neutral" />
</behaviorExtensions>
</extensions>
Declare the behavior:
<behaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp/>
<CrossDomainServiceBehavior/>
</behavior>
</endpointBehaviors>
<behaviors>
Add the behavior to the binding (here as example one called webHttp):
<bindings>
<webHttpBinding>
<binding name="webHttp"
maxReceivedMessageSize="20000000" >
<security mode="None">
<transport clientCredentialType = "None"/>
</security>
</binding>
<CrossDomainServiceBehavior />
</webHttpBinding>
</bindings>
Finally, add the behavior to your service endpoint, here in example one that implements ISomeService:
<endpoint address="" binding="webHttpBinding" contract="Services.ISomeService" bindingConfiguration="webHttp" behaviorConfiguration="CrossDomainServiceBehavior "/>
http-request-headers
tohttp-request-headers="*"
to make sure that requests can go though is allowed, then work backwards as you add restrictions. If with all headers allowed it still does not go through then the issue is elsewhere. a fire wall setting maybe? – Nkosi