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

查看:127
本文介绍了如何使用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消息,反序列化为Plain .NET对象(PO​​NO)并让你使用它。事实上,当我在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 post消息之外的其他内容。 (关于此问题的堆栈溢出)。

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中这很好,但如果你是杜安ga自我托管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天全站免登陆