[英]WCF error : 405 Method Not Allowed
為這個問題發瘋。 我有一個包含 2 個項目的解決方案,其中一個是帶有 jquery ajax 調用的普通舊 html,而另一個是 WCF 服務。 html 頁面將向 WCF 服務發出 ajax 調用以獲取 json 字符串並將其用於顯示目的。
現在的問題是,每當我在調試模式下運行時,html 頁面和 WCF 都將以不同的端口啟動。 這在我執行測試時為我創建了一個跨域問題(即在 Firefox 中調用 type = OPTIONS 時出現 405 Method Not Allowed 錯誤)。 我會三次檢查我的 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>
任何人有任何想法擺脫這個惱人的問題?
編輯:補充一下,我正在使用 VS Studio 2012 附帶的 IIS Express 運行調試
添加 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);
}
});
});
您需要使用 JSONP 進行跨域調用以繞過瀏覽器限制,並更新您的 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>
然而,它是一個舊線程,但我想添加我對我遇到的問題以及我為 CORS 工作獲得的解決方案的評論。 我正在以下環境中開發 Web 服務:
大多數人提到在 web.config 中<webHttpBinding>
下的標記中添加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 調用中獲取數據。 祝你好運!
只是想在底部附加一些與 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="")
並調用適當的方法,將適當的標頭加載到調用方的響應(包括該端點的適當的“Access-Control-Allow-Method”列表)。 托管 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");
}
嘗試使用。 WebInvoke(Method = "POST")
而不是WebInvoke(Method = "GET")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.