C# WCF 错误:405 方法不允许
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13228995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WCF error : 405 Method Not Allowed
提问by ipohfly
Going nuts with this issue. I have a solution with 2 projects, one of them is a plain old html with jquery ajax call while the other is a WCF service. The html page will issue a ajax call to the WCF service to get a json string and use it for display purpose.
对这个问题发疯了。我有一个包含 2 个项目的解决方案,其中一个是带有 jquery ajax 调用的普通旧 html,而另一个是 WCF 服务。html 页面将向 WCF 服务发出 ajax 调用以获取 json 字符串并将其用于显示目的。
Now the issue is whenever i run in debug mode, both the html page and the WCF will be started with different port. And this has created a cross-origin issue for me when i perform testing (i.e. getting a 405 Method Not Allowed error with the calling type = OPTIONS in Firefox). I'd triple check the call method on my ajax script and the WCF service is the same (GET).
现在的问题是,每当我在调试模式下运行时,html 页面和 WCF 都将以不同的端口启动。这在我执行测试时为我创造了一个跨域问题(即在 Firefox 中使用调用类型 = OPTIONS 获得 405 Method Not Allowed 错误)。我会三重检查我的 ajax 脚本上的调用方法,并且 WCF 服务是相同的 (GET)。
I'd search google but found that either i have to install a extension or perform some configuration on IIS, which i found cumbersome since what i'm doing is something simple. Following one example, I'd add in the following configuration in my web.config but it didn't work:
我会搜索谷歌,但发现要么我必须安装扩展程序,要么在 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>
Any one has any idea to get rid of this annoying issue?
任何人都知道摆脱这个烦人的问题吗?
EDIT:Just to add, I'm running the debug with IIS Express that comes together with the VS Studio 2012
编辑:补充一点,我正在使用与 VS Studio 2012 一起提供的 IIS Express 运行调试
Add in WCF Code and Updated web.config
添加 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
}
My Script:
我的脚本:
$(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);
}
});
});
采纳答案by Jude Fisher
You need to use JSONP for a cross-domain call to get round the browser restrictions, and to update your web.config with crossDomainScriptAccessEnabledset to true to get round server ones. There's a good example in the answer here: how to avoid cross domain policy in jquery ajax for consuming wcf service?
您需要使用 JSONP 进行跨域调用以绕过浏览器限制,并将您的 web.configcrossDomainScriptAccessEnabled设置为 true 以绕过服务器限制。这里的答案中有一个很好的例子:如何避免 jquery ajax 中的跨域策略使用 wcf 服务?
You may also have a problem with GET requests. Try the fixes outlined here: Making a WCF Web Service work with GET requests
您可能还会遇到 GET 请求的问题。尝试此处概述的修复程序: 使 WCF Web 服务与 GET 请求一起工作
Altogether, you want a web.config that looks something like this:
总而言之,您需要一个看起来像这样的 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>
(Note that both the service and the endpoint have behaviours attached, allowing webHttp calls and httpGet calls respectively, and that the binding has crossDomain access explicitly enabled).
(请注意,服务和端点都附加了行为,分别允许 webHttp 调用和 httpGet 调用,并且绑定显式启用了跨域访问)。
... a service method decorated like this:
... 一个这样装饰的服务方法:
[ServiceContract]
public interface IMyService
{
[WebGet] // Required Attribute to allow GET
[OperationContract]
string MyMethod(string MyParam);
}
... and a client call using JSONP:
...以及使用 JSONP 的客户端调用:
<script type="text/javascript">
$(document).ready(function() {
var url = "...";
$.getJSON(url + "?callback=?", null, function(result) { // Note crucial ?callback=?
// Process result
});
});
</script>
回答by RamKr
However its an old thread, but I would like add my comment about the problems I faced and the solution I got for working of CORS. I am developing a web service in the following environment:
然而,它是一个旧线程,但我想添加我对我面临的问题的评论以及我为 CORS 工作得到的解决方案。我正在以下环境中开发 Web 服务:
- WCF web service.
- .NET 3.5 framework.
- Added wcf web service into existing asp.net website.
- Visual Studio 2008
- WCF 网络服务。
- .NET 3.5 框架。
- 将 wcf Web 服务添加到现有的 asp.net 网站中。
- 视觉工作室 2008
Most of the people mentioned about adding the crossDomainScriptAccessEnabledattribute in tag under <webHttpBinding>in web.config. I am not sure this works or not but its not available in 3.5 version, so I had no choice. I also found that adding the following tags in web.config will work...
大多数人提到在 web.configcrossDomainScriptAccessEnabled下的标签中添加属性<webHttpBinding>。我不确定这是否有效,但它在 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>
<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>
but no luck...kept getting 405 method not allowed errors
但没有运气...不断获得 405 方法不允许错误
After struggling a lot with these options I found another solution to add these headers in global.asax file dynamically as per the given below...
在对这些选项进行了大量努力之后,我找到了另一种解决方案,可以按照下面给出的动态在 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();
}
}
And remove the from web.config. Publish the website and continue to client side jquery/ajax...and you will get the data from api calls. Good Luck!
并从 web.config 中删除。发布网站并继续客户端jquery/ajax...你将从api调用中获取数据。祝你好运!
回答by jeremyh
Just wanted to append some issues with the CORS rework at the bottom - The problem with it is that if your input does not support the GET and POST method, the OPTIONS request is not actually returning the correct allowed headers. It really isn't looking at which methods are actually allowed on the WCF endpoint - its just artificially saying "GET, POST" are allowed for every single endpoint in the application when a client performs an OPTIONS request (which is really the client asking what is supported).
只是想在底部附加一些与 CORS 返工有关的问题 - 它的问题在于,如果您的输入不支持 GET 和 POST 方法,则 OPTIONS 请求实际上并未返回正确的允许标头。它实际上并不是在查看 WCF 端点上实际允许使用哪些方法 - 它只是人为地说当客户端执行 OPTIONS 请求时,应用程序中的每个端点都允许“GET,POST”(这实际上是客户端询问什么支持)。
This is probably OK, if you aren't really relying on the information in the OPTIONS method to return you a valid list of methods (as is the case with some CORS requests) - but if you are, you will need to do something like the solution on this question: How to handle Ajax JQUERY POST request with WCF self-host
这可能没问题,如果您不是真的依赖 OPTIONS 方法中的信息来返回有效的方法列表(如某些 CORS 请求的情况)-但如果是,则需要执行以下操作这个问题的解决方案: How to handle Ajax JQUERY POST request with WCF self-host
Basically, each endpoint should implement:
基本上,每个端点都应该实现:
Webinvoke(Method="OPTIONS", UriTemplate="")
Webinvoke(Method="OPTIONS", UriTemplate="")
and call an appropriate method which loads the proper headers to the response (including the proper "Access-Control-Allow-Method" list for that endpoint) to the caller. It kind of sucks that hosted WCF endpoints don't do this for us automatically, but this is a workaround that allows finer control over the endpoint. In that solution the proper response headers are loaded at the endpoint implementation:
并调用适当的方法,该方法将正确的标头加载到响应中(包括该端点的正确“访问控制允许方法”列表)给调用者。托管的 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");
}
回答by Hafeez Liaquat
try to use.
WebInvoke(Method = "POST")instead of WebInvoke(Method = "GET")
尝试使用。
WebInvoke(Method = "POST")代替WebInvoke(Method = "GET")

