将JSON数据从JQuery发送到WCF REST方法时出现问题

the*_*onk 22 rest wcf jquery http-options-method

我在使用jquery将一些json数据发布到我在WCF服务上的rest方法时遇到了一些麻烦.

在WCF方面,这是操作合同:

[OperationContract]
[WebInvoke(Method = "POST",
           BodyStyle = WebMessageBodyStyle.Bare,
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
Run Code Online (Sandbox Code Playgroud)

双方MyResultMyRequest标有所有必要DataContractDataMember属性和服务暴露WebHttp端点.

在JQuery方面,这是我的函数调用:

var jsonStr = JSON.stringify(reqObj);

$.ajax({
    type: "POST",
    dataType: "json",
    url: "http://localhost/MyService/PostSomething",
    contentType: "application/json; charset=utf-8",
    data: jsonStr,
    success: function (html) {
        alert(html);
    }
});
Run Code Online (Sandbox Code Playgroud)

这个请求永远不会到达我的方法(我每次都得到一个405方法不允许),并查看Charles的请求如下所示:

OPTIONS /MyService/PostSomething HTTP/1.1
Host: localhost
Cache-Control: max-age=0
Access-Control-Request-Method: POST
Origin: null
Access-Control-Request-Headers: Content-Type, Accept
Accept: */*
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Run Code Online (Sandbox Code Playgroud)

对此有些奇怪的事情:

  1. 方法是OPTIONS而不是POST
  2. 内容类型(在另一个选项卡中)显示text/html; charset=UTF-8而不是json
  3. JSON数据无处可见

但是,如果我在Charles中修改请求以使其标题与此处的解决方案类似,那么一切正常:

POST /MyService/PostSomething HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: localhost
Content-Length: 152

{"Id":"", "Name":"testspot","Description":"test" } 
Run Code Online (Sandbox Code Playgroud)

在这里查看教程和其他问题,其他人已经设法让JQuery发布到这样的WCF REST方法,我不知道我在这里做错了什么..

哦,为了放置一些上下文,这是一个WCF 4服务,我正在使用JQuery 1.4.4.

谢谢,

更新:

经过一番阅读并感谢Darrel指出我的跨域规范,我设法通过在服务接口上对我的服务进行一些小改动来进一步改进:

[OperationContract]
[WebInvoke(Method = "*",
           BodyStyle = WebMessageBodyStyle.Bare,
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
Run Code Online (Sandbox Code Playgroud)

在实现中,我需要检查传入的请求是否适用于OPTIONS,并且在这种情况下返回一些头文件而不是执行预期的工作:

if (WebOperationContext.Current.IncomingRequest.Method == "OPTIONS")
{
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");

    return null;
}
Run Code Online (Sandbox Code Playgroud)

然后该方法被调用两次,第一次服务器返回null但是向客户端添加了一些头,然后实际请求使用POST作为方法,服务器继续正常处理请求.

Dar*_*ler 8

这似乎是一个避免跨域调用的Firefox.见http://www.petefreitag.com/item/703.cfm

这里的规范是http://www.w3.org/TR/cors/,经过非常简短的阅读,似乎因为你正在进行跨域调用,你的服务应该实现OPTIONS方法并返回一些允许发送POST方法的标头.

  • @DarrelMiller.如何为OPTIONS实现处理程序? (3认同)