如何使用 WCF 自托管处理 Ajax JQUERY POST 请求 [英] How to handle Ajax JQUERY POST request with WCF self-host

查看:35
本文介绍了如何使用 WCF 自托管处理 Ajax JQUERY POST 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建 RESTful WCF 服务器的原因有很多(这很容易),如果您可以避免 ASP 和它的安全框(如果您所做的只是简单的返回信息请求),那就更好了.请参阅:http://msdn.microsoft.com/en-us/library/ms750530.aspx 如何做到这一点.

There are many reasons create a RESTful WCF server (it is easy) and even better if you can avoid ASP and it's security box (if all you are doing is simple requests to return information). See: http://msdn.microsoft.com/en-us/library/ms750530.aspx on how to do this.

我发现处理 AJAX (JQUERY) GET 请求很容易.但是在 POST 中处理 JSON 很棘手.

What I found is that handling AJAX (JQUERY) GET requests is easy. But dealing with JSON in a POST is tricky.

以下是一个简单的 GET 请求合约示例:

Here is an example of a simple GET request contract:

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    String Version();

实现就在这里(返回一个 JSON)

And the implementaion is here (which returns a JSON)

    public partial class CatalogService : ICatalogService
{
    public String Version()
    {
        mon.IsActive = true;
        this.BypassCrossDomain();
        ViewModel.myself.TransactionCount++;
        return ViewModel.myself.VersionString;
    }
}

啊,但是如果你想发布一些 JSON 怎么办.你会发现很多关于堆栈溢出的文章告诉你你所要做的就是:

Ah, but what if you want to POST some JSON. You will find lots of articles on stack overflow that tell you all you have to do is this:

    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    BuildResponse BuildToby(BuildRequest request);

它将接收 JSON 消息,反序列化为普通 .NET 对象 (PONO) 并让您使用它.事实上,当我在 Fiddler 中构建请求时,这工作得很好.

which will receive a JSON message, de-serialize into a Plain .NET object (PONO) and let you work with it. And indeed, this worked fine when I constructed the request in Fiddler.

POST /BuildToby HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:4326
Content-Length: 1999

然而,当你在 JQUERY 1.8 中使用下面的 AJAX 时,你会发现一个惊喜:

However, when you use the following AJAX in JQUERY 1.8, you will find a SURPRISE:

通过指定application/json"的内容类型,您会发现浏览器会触发预检"检查,以查看是否允许您发布 www-url-encloded 以外的内容留言.(有堆栈溢出的注释).

It by specifying content-type of "application/json" you will find that there is a "preflight" check that is fired off by the browser to see if you are allowed to POST something other than a www-url-encloded post message. (there are notes in stack overflow about this).

    var request = JSON.stringify({ FrameList: ExportData.buildList });
    var jqxhr = $.ajax({
    type: "POST",
    url: "http://localhost:4326/BuildToby",
    data: request,
    contentType: "application/json; charset=utf-8",
    dataType: "json"
});

这里是 fiddler 报告的内容:(注意这不是 POST 消息,而是 OPTIONS 消息).

and here is what fiddler reports: (Note it is not a POST message, but a OPTIONS message).

OPTIONS http://localhost:4326/BuildToby HTTP/1.1
Host: localhost:4326
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://ysg4206
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

发生的情况是浏览器(在本例中为 Firefox)必须使用 OPTIONS HTTP 消息对服务器进行额外调用,以查看是否允许(这种内容类型的)POST.

What has happened is that a browser (in this case Firefox) has to make a extra call to the server, with a OPTIONS HTTP message, to see if a POST is allowed (of this content type).

所有关于解决这个问题的文章都是关于编辑GLOBAL.ASAX如果您使用的是 ASP.NET,则很好,但如果您使用的是自托管 WCF,则无用.

All the articles about fixing this are about editing GLOBAL.ASAX which is fine if you are in ASP.NET but are useless if you are doing a self-host WCF.

所以现在你看到了问题(抱歉我啰嗦了这么多,但我想把这篇文章写成一篇完整的文章,以便其他人可以了解结果).

So now you see the question (sorry for being so long winded, but I wanted to make this a complete article so that others can follow the results).

推荐答案

好的,现在有一些真正的 MSDN 专家已经写了解决方案,但我无法弄清楚:http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx

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

但我想出了一个简单的解决方案.至少在 WCF 4.5 中,您可以添加自己的 OperationContract 来处理 OPTIONS 请求:

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();

请注意,方法签名是无效的,并且没有参数.这将首先被调用,然后将调用 POST 消息.

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

GetOptions 的实现是:

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.

您可能还想将此属性添加到您的服务类,以便您可以序列化大型 JSON:

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", "*");
    }
}

请注意,我有一个名为 BypassCrossDomain() 的小辅助方法,我在所有 POST 和 GET 方法上调用它,以便我可以处理跨域调用.

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.

我在这里花了很多研究时间(在 MSDN 论坛、堆栈溢出、博客中),我希望这能帮助其他人尝试做这类项目.

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.

这篇关于如何使用 WCF 自托管处理 Ajax JQUERY POST 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆