gpt4 book ai didi

wcf - 如何使用 WCF 自托管处理 Ajax JQUERY POST 请求

转载 作者:行者123 更新时间:2023-12-03 22:03:23 24 4
gpt4 key购买 nike

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

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

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

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

实现在这里(返回 JSON)

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

啊,但是如果你想 POST 一些 JSON 该怎么办?您会发现很多有关堆栈溢出的文章,它们告诉您所需要做的就是:

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

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

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

但是,当您在 JQUERY 1.8 中使用以下 AJAX 时,您会发现一个惊喜:

通过指定“application/json”的内容类型,您会发现浏览器会触发“预检”检查,以查看是否允许您发布除 www-url 编码之外的内容发布消息。 (有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 消息)。

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。

所有有关解决此问题的文章都是关于 editing GLOBAL.ASAX如果您使用 ASP.NET,这很好,但如果您正在使用自托管 WCF,则毫无用处。

所以现在你看到了这个问题(很抱歉这么长篇大论,但我想把这篇文章写成一篇完整的文章,以便其他人可以遵循结果)。

最佳答案

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

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

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

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

GetOptions的实现是:

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

这确实是您所要做的。

您可能还想将此属性添加到您的服务类中,以便可以序列化大型 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 方法上调用该方法,以便我可以处理跨域调用。

我在这里花费了大量的研究时间(在 MSDN 论坛、堆栈溢出、博客),我希望这能帮助其他尝试做此类项目的人。

关于wcf - 如何使用 WCF 自托管处理 Ajax JQUERY POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15369619/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com