2011-02-02 61 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(); 
    } 
    
相關問題