1

Problem

Whenever I try to sent a POST request to my WCF service (running locally on IIS), I get:

Access Denied

My WCF config (relevant code only)

I added the below to allow the different methods, and I'm able to get the info from a Request Method: 'GET', but not a POST

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*"/>
    <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
    <add name="Access-Control-Allow-Methods" value="GET,POST,DELETE" />
    <add name="Access-Control-Max-Age" value="1728000" />
  </customHeaders>
</httpProtocol>

Ajax call

Here is my ajax call, whenever I try to create a new 'Project'

$.ajax({
    url: baseAddress + "projects/create",
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify({
        'Title': 'Test Title',
        'Customer': {
            'Name': 'Test Name'
        }
    })
})

Service implementation

Here's the IService.cs with the UriTemplate and the Method = 'POST'

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/projects/create")]
int CreateProject(ProjectDTO project);

EXTRA INFO

Whenever I watch the headers through google chrome, I see the Request Method is OPTIONS and the response Access-Control-Allow-Methods: GET, POST, DELETE, but still, I can't make POST requests (Refer to this).

How do I handle the request method OPTIONS correctly in a WCF service?

EDIT

The funny thing is that the response says: Access-Control-Allow-Methods: GET, POST, etc., which means that since the request asks: Access-Control-Request-Method: POST, it should be allowed to sent this request, but for some reason I get this Access Denied

EDIT 2

I'm aware that the Request Method: OPTIONS, but the OPTIONS asks my service if it's allowed to do a POST request, where the service answers back with Access-Control-Allow-Methods: GET, POST, etc. There by saying POST IS allowed.

Detilium
  • 2,868
  • 9
  • 30
  • 65
  • Shouldn't "Access-Control-Allow-Headers" contain "Accept, Content-Type, Origin" (missing Origin)? – Rick Burns Sep 01 '15 at 12:44
  • @UncleRico Doesn't make any difference either way though :) – Detilium Sep 01 '15 at 12:46
  • Your headers otherwise look like they should. Have you tried using a manual header override in the projects/create controller [ie: Response.AppendHeader(...)] ? – Rick Burns Sep 01 '15 at 12:49
  • I'm not sure what you mean? Could you elaborate please? – Detilium Sep 01 '15 at 12:51
  • Like here: http://enable-cors.org/server_aspnet.html. Can you put a copy of your C:\Windows\System32\LogFiles\HTTPERR\httperr.log from the 172.20.40.125 server here? It may not be an issue with the headers at all but a piece of code within the projects/create controller. – Rick Burns Sep 01 '15 at 12:56
  • There's a bunch of crap in there and most of it is just localhost. This is what the cross origin looks like: `2015-09-01 12:53:55 172.20.40.125 2028 172.20.40.125 80 - - - - - Timer_ConnectionIdle -` – Detilium Sep 01 '15 at 12:59

3 Answers3

0

Will it Support OPTIONS request? According to CORS, the first request will be preflight request. i.e OPTIONS to verify and the next GET,POST will be success based on OPTIONS response headers.

Please refer more here

Suresh
  • 1,063
  • 1
  • 11
  • 16
  • I tried this: `` as well. But no difference. By sending the `OPTIONS` it asks 'May I send `POST`?' and as the `Allow-Method` has `POST` in it, it should be allowed but it's not. – Detilium Sep 02 '15 at 06:19
0

I had a WCF service that I needed to call from a JavaScript client via AJAX - so I first added an endpoint with a 'webHttpBinding' to allow access over pure HTTP (i.e. no SOAP, see this answer if curious: REST / SOAP endpoints for a WCF service).

Then, this is how I enabled CORS for my WCF service:

  1. Add a Global.asax file (if you don't have one already)

  2. Implement the following method:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        // Add CORS headers to allow a JavaScript client to call the WCF service via AJAX from a different domain
        var requestOrigin = Request.Headers.Get("Origin");
        Log.Debug($"Processing request from Origin: '{requestOrigin}'");
    
        // Accommodate for all possible cross-domain requests
        if (string.IsNullOrEmpty(requestOrigin) == false)
        {
            if (requestOrigin.Contains("devdomain"))
            {
                AddAllowedOrigin("http://devdomain");
            }
            else if (requestOrigin.Contains("qasdomain"))
            {
                AddAllowedOrigin("http://qasdomain");
            }
            else if (requestOrigin.Contains("prddomain"))
            {
                AddAllowedOrigin("http://prddomain");
            }
        }
    
        // Respond to an OPTIONS pre-flight request
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
            HttpContext.Current.Response.End();
        }
    }
    
    private static void AddAllowedOrigin(string origin)
    {
        Log.Debug($"Adding Access-Control-Allow-Origin header to response to allow Origin: '{origin}'");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
    }
    

Note that the "Access-Control-Allow-Origin" header has to be added to the response to the both the OPTIONS pre-flight request, and every subsequent request sent from the cross-domain (e.g. 'devdomain' etc)

JTech
  • 3,420
  • 7
  • 44
  • 51
0

Add the following line to all the methods in the WCF Service.

WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");

Requires the following import

System.ServiceModel.Web;

Refer this for original answer

PoomaniGP
  • 80
  • 1
  • 1
  • 11