I am needing to make a cross domain POST request to a WCF service hosted by an executable, NOT from IIS. The purpose is to pass in an array of id strings from a web client, which the WCF service will use to find and return logs pertaining to those ids.
I believe I am close and that the main piece I'm missing is a piece of configuration in the app.config file which adds a custom header. I will note that elsewhere in my solution there is a web.config for another service that describes the behavior I'm looking for, which includes:
<httpProtocol>
<customHeaders>
<!-- http://stackoverflow.com/questions/12458444/enabling-cross-origin-resource-sharing-on-iis7 -->
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type,Accept" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Timing-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Now my issue with the above code is that it resides in a web.config file for an IIS hosted service. I need to be able to describe that custom header in an app.config for my service which I am hosting in an executable (I have provided the method in question below).
I have been trying to solve this for days, and thus far, aside from the configuration confusion I'm looking for help with, it's my understanding that this syntax is alright for calling the service:
var settings: JQueryAjaxSettings = {};
settings.async = true;
settings.crossDomain = true;
settings.url = this.getLogEntriesByIdResource;
settings.method = "POST";
settings.type = "POST";
settings.dataType = 'JSON';
settings.headers = {
"content-type": "application/json",
"cache-control": "no-cache"
}
settings.data = JSON.stringify(ids);
jQuery.ajax(settings).done(function (response) {
console.log(response);
});
and that this is a good pass at a WCF endpoint which the above code calls:
[OperationContract, CorsEnabled]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetLogEntriesById")]
[Description("Request entities or entity updates for a particular time and place")]
public List<LogEntryInfo> GetLogEntriesById(string[] ids)
{
List<LogEntryInfo> results = new List<LogEntryInfo>();
List<ILogEntry> rels = Gateway.MongoDbInstance.ReturnLogEntries(ids.ToList());
rels.ForEach(e => results.Add(new LogEntryInfo(e)));
return results;
}
Additionally, here is the code which sets up my webServiceHost:
public LogEntryRestService(string baseAddress, string endpoint)
{
_baseAddress = baseAddress;
_endpoint = endpoint;
_webServiceHost = new WebServiceHost(this, new Uri(baseAddress));
var webBinding = new WebHttpBinding(WebHttpSecurityMode.None) { CrossDomainScriptAccessEnabled = true };
ServiceEndpoint ep = _webServiceHost.AddServiceEndpoint(typeof(LogEntryRestService), webBinding, endpoint);
WebHttpBehavior webBehavior = new WebHttpBehavior();
webBehavior.HelpEnabled = true;
ep.EndpointBehaviors.Add(webBehavior);
ep.EndpointBehaviors.Add(new EnableCorsEndpointBehavior());
Program.LogMessage(string.Format("Initializing LogEntry REST endpoint BaseAddress: {0} EndpointName: {1}",
_webServiceHost.BaseAddresses[0], endpoint));
_webServiceHost.Open();
}
I'll also point out that standard calls from Postman with JSON body specified to the endpoint are working perfectly. I am aware that Postman (a Chrome extension) doesn't adhere to CORS the same way a web page does. My calling ajax code is the same suggested calling code that Postman provides for jQuery ajax, so I assume that means I'm seeing a CORS issue.
I am a little exhausted from all of this configuration and CORS appeasement and I really appreciate the fresh eyes and the help!
UPDATE
So I tried deploying my current code (what I've shared above) to an actual server instance, as opposed to debugging on my local box, and found that everything is working fine. I am however, still receiving errors locally that I would like to resolve though. That error is described by this response when my locally debugged client is calling my locally debugged service:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Service</title>
<style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
</head>
<body>
<div id="content">
<p class="heading1">Service</p>
<p xmlns="">Method not allowed. Please see the <a rel="help-page" href="http://localhost/LogEntryService/help">service help page</a> for constructing valid requests to the service.</p>
</div>
</body>
</html>
I'll also note that the Request Method is shown as "OPTIONS" rather that POST, which is what it is supposed to be, and is the behavior that I see when running all this code on the dedicated server.
Any reason why a POST method would default to an OPTIONS method? I assume I am back to square one in that to solve this I need to enable CORS on my non-IIS hosted web service. Thanks again for any help or insight!
UPDATE
I've included below a screen cap of both a fiddler inspection of the request and the Chrome dev tools network view of the request.