2012-11-05 175 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")