2012-11-05 93 views
15

對此問題堅持不懈。我有一個解決方案與2個項目,其中之一是一個簡單的舊jQuery jQuery Ajax調用,而另一個是WCF服務。該html頁面將發出一個ajax調用WCF服務來獲取一個json字符串並將其用於顯示目的。WCF錯誤:405方法不允許

現在的問題是,每當我運行在調試模式下,html頁面和WCF都將以不同的端口啓動。當我執行測試時(例如,在Firefox中調用type = OPTIONS時,得到405方法不允許錯誤),這就爲我創建了一個跨源問題。我會三重檢查我的ajax腳本的調用方法,並且WCF服務是相同的(GET)。

我會搜索谷歌,但發現無論我必須安裝擴展或在IIS上執行一些配置,我發現很麻煩,因爲我正在做的事情很簡單。下面的一個例子,我要補充在我的web.config以下的配置,但它沒有工作:

<system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="crossDomain" crossDomainScriptAccessEnabled="true" /> 
     </webHttpBinding> 
    </bindings> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="MobileService.webHttpBehavior"> 
      <webHttp /> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior name="MyServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    <services> 
     <service name="MobileService.SimpleMemberInfo" behaviorConfiguration="MyServiceBehavior"> 
     <endpoint address="" binding="webHttpBinding" contract="MobileService.IMemberInfo" bindingConfiguration="crossDomain" behaviorConfiguration="MobileService.webHttpBehavior"> 
     </endpoint> 
     </service> 
    </services> 
    </system.serviceModel> 
    <system.webServer> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
     <add name="Access-Control-Allow-Methods" value="GET" /> 
     <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> 
     </customHeaders> 
    </httpProtocol> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

任何一個已經擺脫這惱人的問題的任何想法?

編輯:我想補充,我正在與IIS快遞,與VS工作室2012

一起來到添加在WCF代碼的調試和更新的web.config

[ServiceContract] 
public interface IMemberInfo 
{ 
    [WebInvoke(Method = "GET", 
      BodyStyle = WebMessageBodyStyle.Wrapped, 
      ResponseFormat = WebMessageFormat.Json 
    )] 
    [OperationContract] 
    string GetMemberInfoById(); 
    // TODO: Add your service operations here 
} 

我的腳本:

$(document).ready(function() { 
    $.ajax("http://localhost:32972/SimpleMemberInfo.svc/GetMemberInfoById", { 
     cache: false, 
     beforeSend: function (xhr) { 
      $.mobile.showPageLoadingMsg(); 
     }, 
     complete: function() { 
      $.mobile.hidePageLoadingMsg(); 
     }, 
     contentType: 'application/json', 
     dataType: 'json', 
     type: 'GET', 
     error: function() { 
      alert('Something awful happened'); 
     }, 
     success: function (data) { 
      var s = ""; 

      s += "<li>" + data + "</li>"; 
      $("#myList").html(s); 

     } 
    }); 
}); 
+0

此鏈接可能會幫助http://stackoverflow.com/questions/2202500/wcf-service-405-method-not-allowed-exception – Mihai

+0

感謝。我試過了,但沒有奏效。 – ipohfly

+0

ops ok ...但如果沒有一個答案真的有幫助,那麼我應該選擇最接近的一個? – ipohfly

回答

8

您需要使用JSONP進行跨域調用才能獲得t他瀏覽器的限制,並更新您的web.config與crossDomainScriptAccessEnabled設置爲true以獲得一輪服務器。這裏有個很好的例子:how to avoid cross domain policy in jquery ajax for consuming wcf service?

您也可能遇到GET請求的問題。嘗試此處列出的修補程序: Making a WCF Web Service work with GET requests

總之,你想要一個web.config,看起來是這樣的:

<bindings> 
    <webHttpBinding> 
    <binding name="crossDomain" crossDomainScriptAccessEnabled="true" /> 
    </webHttpBinding> 
</bindings> 
<behaviors> 
    <endpointBehavior> 
    <behavior name="restBehavior"> 
     <webHttp /> 
    </behavior> 
    </endpointBehavior> 
    <serviceBehavior>   
    <behavior name="MyServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehavior> 
</behaviors> 
<services> 
    <service name="..." behaviorConfiguration="MyServiceBehavior"> 
    <endpoint address="" binding="webHttpBinding" bindingConfiguration="crossDomain" 
       contract="..." behaviorConfigurations="restBehavior" /> 
    </service> 
</services> 

(請注意,無論是服務和端點都附着的行爲,讓webHttp電話和httpGet分別調用,並且綁定具有顯式啓用的跨域訪問)。

...服務方法裝飾這樣的:

[ServiceContract] 
public interface IMyService 
{ 
    [WebGet] // Required Attribute to allow GET 
    [OperationContract] 
    string MyMethod(string MyParam); 
} 

...和使用JSONP客戶電話:

<script type="text/javascript"> 
$(document).ready(function() { 
    var url = "..."; 
    $.getJSON(url + "?callback=?", null, function(result) { // Note crucial ?callback=? 
     // Process result 
    }); 
}); 
</script> 
+0

謝謝。剛剛嘗試過,但沒有成功,與客戶端示例的鏈接已經失效。我嘗試在我的web.config中添加crossDomain綁定,但它不起作用。 – ipohfly

+0

只是谷歌或在這裏搜索JSONP - 有大量的例子,如:http://stackoverflow.com/questions/2681466/jsonp-with-jquery只修復服務器端不會工作。 – JcFx

+0

另外 - 你可以顯示你的WCF代碼?除了允許Web中的WebGet。配置(按照上面的例子),你需要用正確的屬性修飾你的WCF方法。 – JcFx

7

但是它的一個古老的線程,但我想加我評論我遇到的問題以及我爲CORS工作所獲得的解決方案。 我在以下環境中開發Web服務:

  1. WCF Web服務。
  2. .NET 3.5框架。
  3. 將wcf web服務添加到現有的asp.net網站中。
  4. 的Visual Studio 2008

最多大約在web.config中<webHttpBinding>下加入TAG中crossDomainScriptAccessEnabled屬性中提到的人。我不確定這是否有效,但在3.5版本中不可用,所以我別無選擇。我還發現,添加以下標籤的web.config工作...

<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> </customHeaders> </httpProtocol>

,但沒有運氣......不斷獲得405方法不被允許錯誤

掙扎了很多使用這些選項後我發現了另一個解決方案,在Global.asax文件,這些頭添加動態按低於給定的...

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
    { 
     HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     HttpContext.Current.Response.End(); 
    } 
} 

而且從web.config中刪除。發佈網站並繼續到客戶端的jquery/ajax ...並且您將從api調用中獲取數據。祝你好運!

+0

不起作用仍然從選項中獲得405。 –

2

只想在底部附加一些CORS返工問題 - 問題是如果您的輸入不支持GET和POST方法,則OPTIONS請求實際上並沒有返回正確的允許標題。它實際上並沒有考慮在WCF端點上實際允許使用哪些方法 - 當客戶端執行OPTIONS請求時(這真的是客戶端問什麼問題),它只是人爲地說「GET,POST」被支持)。

如果您不是真的依賴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"); 
    } 
-2

嘗試使用。 WebInvoke(Method = "POST") 代替WebInvoke(Method = "GET")