I have WCF Selfhosted service to communicate with local connected printer to print badges. Our browser based application calls local service to print badges. All GET calls perfectly working fine, but POST request always giving CORS error.
GET Call (Works fine)
POST Call - Fails with CORS error, Pre-Flight request is good
C# Code
private void startService_HTTPS(System.Diagnostics.EventLog eventLog)
{
eventLog.WriteEntry("Begin startService.......");
string serviceUrl = Config.protocol_https + "://" + Config.host + ":" + Config.portNumber_https;
WebServiceHost webServiceHost = new WebServiceHost(typeof(Service), new Uri(serviceUrl));
try
{
ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
KeyedByTypeCollection<IServiceBehavior> behaviors = webServiceHost.Description.Behaviors;
ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior()
{
HttpGetEnabled = false,
HttpsGetEnabled = true
};
behaviors.Add(serviceMetadataBehavior);
ServiceDebugBehavior serviceDebugBehavior = webServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
if (serviceDebugBehavior == null)
{
webServiceHost.Description.Behaviors.Add(new ServiceDebugBehavior()
{
IncludeExceptionDetailInFaults = true
});
}
else
{
serviceDebugBehavior.IncludeExceptionDetailInFaults = true;
}
WebHttpBinding webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport)
{
HostNameComparisonMode = HostNameComparisonMode.Exact,
MaxReceivedMessageSize = (long)2147483647,
TransferMode = TransferMode.Streamed,
// CrossDomainScriptAccessEnabled = true
};
ServiceEndpoint serviceEndpoint = webServiceHost.AddServiceEndpoint(typeof(IService), webHttpBinding, serviceUrl);
serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
serviceEndpoint.Behaviors.Add(new EnableCrossOriginResourceSharingBehavior());
webServiceHost.Open();
eventLog.WriteEntry("Started HTTPS services successfully......"+serviceUrl);
// CertManager certs = new CertManager();
// certs.setupCerts(eventLog);
}
catch (CommunicationException cex)
{
Console.WriteLine("An exception occurred: {0}", cex.Message);
eventLog.WriteEntry("Exception "+cex.Message);
eventLog.WriteEntry(cex.StackTrace);
webServiceHost.Abort();
}
}
C# Custom behavior code
public class EnableCrossOriginResourceSharingBehavior : BehaviorExtensionElement, IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
var requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders));
}
public void Validate(ServiceEndpoint endpoint)
{
}
public override Type BehaviorType
{
get { return typeof(EnableCrossOriginResourceSharingBehavior); }
}
protected override object CreateBehavior()
{
return new EnableCrossOriginResourceSharingBehavior();
}
}
public class CustomHeaderMessageInspector : IDispatchMessageInspector
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Dictionary<string, string> requiredHeaders;
public CustomHeaderMessageInspector(Dictionary<string, string> headers)
{
requiredHeaders = headers ?? new Dictionary<string, string>();
}
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
var httpHeader = reply.Properties["httpResponse"] as System.ServiceModel.Channels.HttpResponseMessageProperty;
httpHeader.StatusCode = System.Net.HttpStatusCode.OK;
foreach (var item in requiredHeaders)
{
log.Debug("BeforeSendReply add header " + item.Key + ", val " + item.Value);
httpHeader.Headers.Add(item.Key, item.Value);
}
}
}
I am looking for some help here....
I tried adding custom behaviors to service, but its always failing, looking for some help in resolving this issue.



I don't think it's okay for you to use endpointDispatcher.DispatchRuntime.MessageInspectors.Add to configure Cros policies. It is a method for inserting, modifying, or extending a custom message inspector in the runtime behavior of a service endpoint or a client callback endpoint.
My suggestion:
1.Create a new Global.asax file
2.Add code