How to handle Ajax JQUERY POST request with WCF self-host

隐身守侯 提交于 2019-11-27 04:16:24

Ok, now there are some real MSDN gurus out there who have written solutions, but I cannot figure them out: http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx

But I have come up with a simple solution. At least in WCF 4.5 you can add your own OperationContract for dealing with OPTIONS requests:

    [OperationContract]
    [WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
    void GetOptions();

Note that the method signature is void, and has no arguments. This will get called first, and then the POST message will be called.

The implementation of GetOptions is:

    public partial class CatalogService : ICatalogService
{
    public void GetOptions()
    {
        mon.IsActive = true;
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
    }
}

and that is really all you have to do.

You might also want to add this attribute to your service class, so that you can serialize large JSON:

//This defines the base behavior of the CatalogService. All other files are partial classes that extend the service
[ServiceBehavior(MaxItemsInObjectGraph = 2147483647)]       // Allows serialization of very large json structures
public partial class CatalogService : ICatalogService
{
    PgSqlMonitor mon = new PgSqlMonitor();

    private void BypassCrossDomain()
    {
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
    }
}

Note I have a little helper method called BypassCrossDomain() which I call on all my POST and GET methods, so that I can deal with cross domain calls.

I spent a lot of research time here (in MSDN forums, stack overflow, blogs) and I hope this will help others trying to do these sorts of projects.

One other addition to Dr.YSG's answer, if you need to support the OPTIONS method on endpoints which take POSTS to individual IDs, you will have to implement multiple GetOptions methods:

    [WebInvoke(Method = "OPTIONS", UriTemplate = "")]
    void GetOptions();
    [WebInvoke(Method = "OPTIONS", UriTemplate = "{id}")]
    void GetOptions(string id);

Its really disappointing that WCF/Microsoft can't automatically generation the proper OPTIONS response based on the signature of the endpoint automatically, but at least it can be handled manually.

In addition to what Dr.YSG listed as his answer, I found that I was getting a Firefox notice that a redirect was occurring, and a "405 Method Not Allowed" error. Adding

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

to the GetOptions class seems to have addressed the issue.

After many days searching about it and reading many posts and proposed solutions, i think this question by Dr. YSG was the best resource to understand and solve my problem with angular/wcf/post/CORS etc.

But what really worked for me was this:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.HttpMethod == "OPTIONS")
    {
        Response.End();
    }
}

I understand it is not a full (nor beautiful) solution, since i am using global.asax and there are so many possible scenarios, but i just want to share this alternative, since it may help somebody else eventually.

(Besides adding the headers)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!