2011-02-02 62 views
21

我在使用jquery将一些json数据发布到我的WCF服务中的休息方法方面遇到了一些麻烦。将JSON数据从JQuery发送到WCF REST方法时出现问题

在WCF侧,这里的经营合同:

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

两个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); 
    } 
}); 

这一要求从来没有达到我的方法(我得到一个405不允许的方法每次),并期待在查尔斯的要求是这样的:

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 

几件事情是奇怪的:

  1. 的方法OPTIONS无法发布
  2. 内容类型(在其他标签)表示text/html; charset=UTF-8代替JSON
  3. JSON数据被没有在那里可以看出

但是,如果我修改查尔斯请求,使得它的头是相似该解决方案here,然后一切正常:

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

{"Id":"", "Name":"testspot","Description":"test" } 

看着教程和其他在这里的问题别人设法让jQuery来张贴到WCF REST方法这个样子,和我在一个无所适从我在这里做错了。

哦,放一些上下文,这是一个WCF 4服务,我使用JQuery 1.4.4。

感谢,

UPDATE:

一些更多的阅读和感谢达雷尔指着我对跨域规范后,我设法通过进行一些小的修改,以进一步得到一点我的服务,服务接口:

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

,并在实施中,我需要检查,如果传入的请求是OPTIONS在这种情况下,返回一些头,而不是做intende d工作:

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

于是,该方法被调用了两次,第一次在服务器返回null,但增加了一些头到客户端,然后实际的请求是由具有POST作为方法和服务器继续运行并交易正常请求。

+0

我非常爱你!非常!!!干杯!!! 我不得不在Windows服务应用程序中托管WCF。方法GET工作,但POST从来没有工作,直到我得到方法=“*”使事情工作。在我的情况下,该方法不会被调用两次! – 2014-07-12 07:33:28

+0

似乎没有在这里工作..你可以把一个完整的例子在线? – 2015-04-29 09:37:37

回答

7

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

这样做的规范是在这里http://www.w3.org/TR/cors/和一个非常短暂的读取后,似乎因为你正在做一个跨域调用,您的服务有望实现OPTIONS方法并返回一些标题,让POST方法将被寄出。

0

在你的web.config中你有没有使用webhttpbinding?

只有webhttpbinding支持json。

+0

没有运气,只是将方法的位置移动到localhost/MyService/MyService/PostSomething – theburningmonk 2011-02-02 14:19:27

+0

yup,该服务公开一个webhttp端点 – theburningmonk 2011-02-02 14:59:15

1

更新:

尝试把.SVC为MyService之后,以使URL读取

http://localhost/MyService.svc/PostSomething 

我工作本就一天自己,跨越上里克施特拉尔的博客的一篇文章来:

http://www.west-wind.com/weblog/posts/324917.aspx

这完美的作品对我来说,S o试一试!

希望有帮助! :)

+0

欢呼,让我看看 – theburningmonk 2011-02-02 14:20:00

3

上含有一个提出的解决方案问题上的更新有一定的问题 - 它的问题是,如果你输入不支持POST方法,OPTIONS请求实际上没有返回正确允许的头。其实,它并不是在看哪些方法实际上是允许对WCF终结 - 它只是人为地说:“POST”被允许在应用程序的每一个端点在客户端执行OPTIONS请求(这是真正的客户问什么是支持)。

如果您不是真的依赖OPTIONS方法中的信息来返回一个有效的方法列表(如某些CORS请求的情况),那么这可能是确定的 - 但如果您是的话,您将需要做这样的事情对这个问题的解决方案: How to handle Ajax JQUERY POST request with WCF self-host

基本上,每个端点应该实现:

Webinvoke(Method="OPTIONS", UriTemplate="")

,并调用它加载适当的标题,以响应适当的方法(包括正确“访问控制允许冰毒od“列表)给调用者。它有点糟糕,托管的WCF端点不会自动为我们做这件事,但这是一种解决方法,可以更好地控制端点。 在该解决方案的适当的响应头在端点实现加载:

public void GetOptions() 
    { 
     // The data loaded in these headers should match whatever it is you support on the endpoint 
     // for your application. 
     // For Origin: The "*" should really be a list of valid cross site domains for better security 
     // For Methods: The list should be the list of support methods for the endpoint 
     // For Allowed Headers: The list should be the supported header for your application 

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

除此之外,您应该设置要么在web.config的结合端点“CrossDomainScriptAccessEnabled”标志,或代码在配置端点时用于WebHttpBinding。否则,你又趴在你的头的响应,当你说“访问控制允许来源”为“*”(或URL列表)

0

我就发布一个简短的回答,帮助我,因为其他答案没有。

  • 场景:ajax调用wcf服务。
  • 故障原因:自动从OPTIONS AJAX请求发送POST 请求之前。我的服务无法处理第一个请求。
  • 解决方案:允许OPTIONS请求并对其做出响应。

你需要做什么:

  1. 一下添加到web.config中:

    <system.webServer> 
    <httpProtocol> 
        <customHeaders> 
        <add name="Access-Control-Allow-Origin" value="*" /> 
        <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" /> 
        <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
        </customHeaders> 
    </httpProtocol> 
    

  2. 一下添加到Global.asax.cs中(如果你不在你的解决方案中没有这个文件,然后创建它:添加新项=> Visual C#=>全局应用程序类(默认名称是“Global.asax”)):

    protected void Application_BeginRequest(object sender, EventArgs e) 
    { 
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
            HttpContext.Current.Response.End(); 
    } 
    
相关问题