I remember how I worked in this many years ago and solved it a little differently, namely with 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); } }
To describe the behavior of your WCF service, you must add the CrossDomainServiceBehavior property, which uses CrossDomainPolicyService to dynamically add cross-domain policies. This will prevent the need to add a cross-domain file to the website itself.
Adding behavior from code (for example, using self-serving services):
endPoint.Behaviors.Add(new CrossDomainServiceBehavior());
Or in the case of WCF definitions in config: For the sake of this example, I assume that CrossDomainServiceBehavior is in the Services.CrossDomainServiceBehavior namespace, and the assembly it is in is version 1.0.0.0 with a neutral culture. It also assumes that you have a binding to a service declaration called webHttp.
Behavior Registration:
<system.serviceModel> <extensions> <behaviorExtensions> <add name="CrossDomainServiceBehavior" type="Services.CrossDomainServiceBehavior, CrossDomainServiceBehavior.AssemblyName, Version=1.0.0.0, Culture=neutral" /> </behaviorExtensions> </extensions>
Declare behavior:
<behaviors> <endpointBehaviors> <behavior name="CrossDomainServiceBehavior"> <webHttp/> <CrossDomainServiceBehavior/> </behavior> </endpointBehaviors> <behaviors>
Add the binding behavior (here, as an example, one is 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 the service endpoint, here in the example that implements ISomeService:
<endpoint address="" binding="webHttpBinding" contract="Services.ISomeService" bindingConfiguration="webHttp" behaviorConfiguration="CrossDomainServiceBehavior "/>