I have a console application with a ServiceHost that exposes a URL.When I invoke this URL from a web page i get the error 'from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource'
CORS error
Program.cs
using ServiceHost.Operation;using System;using System.ServiceModel.Description;using System.ServiceModel.Web;using System.ServiceModel;using System.Threading;namespace ServiceHost{ internal class Program { private static AutoResetEvent manualReset; static void Main(string[] args) { try { manualReset = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(StartService); Console.WriteLine("<ENTER> to finish"); Console.WriteLine("<N> to make another call"); ConsoleKeyInfo key; do { key = Console.ReadKey(true); } while (key.Key != ConsoleKey.Enter); manualReset.Set(); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void StartService(Object stateInfo) { Uri baseAddress = new Uri("http://localhost:1234/test"); Type typeFromHandle = typeof(RegisterOperation); Type typeFromHandle2 = typeof(IRegisterOperation); System.ServiceModel.ServiceHost host = CreateListener(baseAddress, typeFromHandle, typeFromHandle2, false); host.Open(); } private static System.ServiceModel.ServiceHost CreateListener(Uri baseAddress, Type implementationType, Type endpointType, bool securityMode) { System.ServiceModel.ServiceHost host = new System.ServiceModel.ServiceHost(implementationType, baseAddress); WebHttpSecurityMode httpSecurityMode = (securityMode ? WebHttpSecurityMode.Transport : WebHttpSecurityMode.None); ServiceEndpoint se = host.AddServiceEndpoint(endpointType, new WebHttpBinding(httpSecurityMode), ""); WebHttpBehavior webBehavior = new WebHttpBehavior() { HelpEnabled = true, DefaultOutgoingRequestFormat = WebMessageFormat.Json, DefaultOutgoingResponseFormat = WebMessageFormat.Json, }; se.EndpointBehaviors.Add(webBehavior); return host; } }}
IRegisterOperation.cs
using System;using System.ServiceModel;using System.ServiceModel.Web;namespace ServiceHost.Operation{ [ServiceContract] public interface IRegisterOperation { [OperationContract, WebInvoke(Method = "*", UriTemplate = "/registeroperation", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] OperationOutput OperationOut(OperationInput input); }}
OperationInput.cs
using System;using System.ComponentModel;using System.Runtime.Serialization;namespace ServiceHost.Operation{ [DataContract] public class OperationInput : IExtensibleDataObject { [DataMember(Name = "JsonMessage")] public string JsonMessage { get; set; } [Browsable(false)] public ExtensionDataObject ExtensionData { get; set; } }}
OperationOutput.cs
using System;using System.ComponentModel;using System.Runtime.Serialization;namespace ServiceHost.Operation{ [DataContract] public class OperationOutput { [DataMember] public string JsonMessage { get; set; } }}
RegisterOperation.cs
using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Linq;namespace ServiceHost.Operation{ public class RegisterOperation : IRegisterOperation { public OperationOutput OperationOut(OperationInput input) { try { OperationOutput result = new OperationOutput(); var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(JsonConvert.SerializeObject(input)); result.JsonMessage = values.Values.FirstOrDefault(); input.JsonMessage = values.Values.FirstOrDefault(); Console.WriteLine(result.JsonMessage); return result; } catch (Exception e) { Console.WriteLine(e.ToString()); return new OperationOutput() { JsonMessage = e.ToString(), }; } } }}
Webpage
<!DOCTYPE html><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" secure="false"/><allow-http-request-headers-from domain="*" headers="*"/></cross-domain-policy><html><head><title>Call Host</title><style> body { font-family: 'Calibri'; }</style></head><body onload='loadQS()'><h1>Test call host</h1><p>URL: <input type='text' disabled='disabled' id='txtURL' value='http://localhost:1234/test/registeroperation' /></p><p><input type="button" onclick="fCallNave();return false;" value="Return" /></p><script> function fCallNave() { var xhr = null; if(typeof XMLHttpRequest != "undefined") { xhr = new XMLHttpRequest(); } else if(typeof window.ActiveXObject != "undefined") { try { xhr = new ActiveXObject("Msxml2.XMLHTTP.4.0"); } catch(e) { try { xhr = new ActiveXObject("MSXML2.XMLHTTP"); } catch(e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xhr = null; } } } } var data = JSON.stringify({'JsonMessage': 'Response from Webpage' }); xhr.withCredentials = true; xhr.onreadystatechange = function () { console.log(this.readyState) try { if (this.readyState == 4 && this.status == 200) { var objResponse = JSON.parse(this.responseText); if ( objResponse.Message == 'OK') { alert('Return ok'); } else { alert('Error'); } } } catch (error) { console.error('onreadystatechange():'+ error); } } try { xhr.timeout = 30000; xhr.open('POST', 'http://localhost:1234/test/registeroperation', true); xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); xhr.send(data); } catch (error) { console.error('xhr.send():'+ error); } }</script></body></html>
Solve the CORS problem.