WCF 错误:405 方法不允许
Posted
技术标签:
【中文标题】WCF 错误:405 方法不允许【英文标题】:WCF error : 405 Method Not Allowed 【发布时间】:2012-10-25 02:31:22 【问题描述】:对这个问题发疯了。我有一个包含 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);
);
);
【问题讨论】:
这个链接可能对***.com/questions/2202500/…有帮助 谢谢。我试过了,但没有用。 算了...但如果没有一个答案真的有帮助,那么我应该选择最接近的一个? 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。 【参考方案1】:对我有用的是启用 IIS 的 WCF 相关功能:
【讨论】:
【参考方案2】:尝试使用。
WebInvoke(Method = "POST")
而不是WebInvoke(Method = "GET")
【讨论】:
没有 cmets 的反对票?谢谢【参考方案3】:但是,它是一个旧线程,但我想就我面临的问题以及我为 CORS 工作得到的解决方案添加我的评论。 我正在以下环境中开发 Web 服务:
-
WCF 网络服务。
.NET 3.5 框架。
在现有的 asp.net 网站中添加了 wcf 网络服务。
Visual Studio 2008
大多数人都提到了在 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 调用中获取数据。祝你好运!
【讨论】:
【参考方案4】:只是想在底部附加一些与 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="")
并调用适当的方法,该方法将适当的标头加载到调用者的响应中(包括该端点的适当“访问控制允许方法”列表)。托管的 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");
【讨论】:
【参考方案5】:您需要使用 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>
【讨论】:
谢谢。刚试过但没有用,客户端示例的链接已失效。我尝试在我的 web.config 中添加跨域绑定,但没有成功。 只要谷歌或在这里搜索 JSONP - 有很多例子,例如:***.com/questions/2681466/jsonp-with-jquery 只修复服务器端是行不通的。 另外 - 你能显示你的 WCF 代码吗?除了允许在 Web.Config 中使用 WebGet(根据上面的示例),您还需要使用正确的属性来装饰您的 WCF 方法。 非常感谢您的帮助。我尝试了新设置但也不起作用,但我还没有尝试过 json 方法。我也更新了我的代码部分。 终于!使用 JSONP 后(回调参数非常重要),它起作用了!!!!一百万谢谢!以上是关于WCF 错误:405 方法不允许的主要内容,如果未能解决你的问题,请参考以下文章
NetworkError:WCF 中不允许使用 405 方法
使用 jquery 查询 wcf rest 服务(不允许 405 方法)