C# WCF错误:不允许使用405方法

C# WCF错误:不允许使用405方法,c#,wcf,jsonp,cors,C#,Wcf,Jsonp,Cors,在这个问题上发疯。我有两个项目的解决方案,其中一个是带有jQueryAjax调用的普通旧html,另一个是WCF服务。html页面将向WCF服务发出ajax调用,以获取json字符串并将其用于显示目的 现在的问题是,无论何时在调试模式下运行,html页面和WCF都将使用不同的端口启动。当我执行测试时,这给我带来了一个跨源问题(例如,在Firefox中调用type=OPTIONS时出现405 Method Not Allowed错误)。我会在ajax脚本上三次检查调用方法,并且WCF服务是相同的(

在这个问题上发疯。我有两个项目的解决方案,其中一个是带有jQueryAjax调用的普通旧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>
我的剧本:

$(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);

        }
    });
});
$(文档).ready(函数(){
$.ajax(”http://localhost:32972/SimpleMemberInfo.svc/GetMemberInfoById", {
cache:false,
发送前:函数(xhr){
$.mobile.showPageLoadingMsg();
},
完成:函数(){
$.mobile.hidePageLoadingMsg();
},
contentType:'应用程序/json',
数据类型:“json”,
键入:“GET”,
错误:函数(){
警惕(可怕的事情发生了);
},
成功:功能(数据){
var s=“”;
s+=“
  • ”+数据+“
  • ”; $(“#myList”).html; } }); });
    您需要使用JSONP进行跨域调用,以绕过浏览器限制,并使用
    crossDomainScriptAccessEnabled
    将web.config更新为true以绕过服务器限制。答案中有一个很好的例子:

    GET请求也可能有问题。尝试下面列出的修复:

    总之,您需要的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>
    
    [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>
    
    
    $(文档).ready(函数(){
    var url=“…”;
    $.getJSON(url+“?回调=?”,null,函数(结果){//Note-critical?回调=?
    //过程结果
    });
    });
    
    然而,这是一个老话题,但我想补充一下我所面临的问题以及我在CORS工作中得到的解决方案。 我正在以下环境中开发web服务:

  • WCF web服务
  • .NET3.5框架
  • 将wcf web服务添加到现有asp.net网站中
  • Visual Studio 2008
  • 大多数人提到在web.config的
    下的标记中添加
    crossDomainScriptAccessEnabled
    属性。我不确定这是否有效,但它在3.5版本中不可用,所以我别无选择。我还发现在web.config中添加以下标记会起作用

    
    

    但运气不好…一直得到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端点上实际允许哪些方法——它只是在客户端执行选项请求时人为地说应用程序中的每个端点都允许“GET,POST”(这实际上是客户端询问支持什么)

    如果您不是真的依赖OPTIONS方法中的信息来返回有效的方法列表(如某些CORS请求),那么这可能是可以的,但是如果您是,您将需要执行类似于此问题解决方案的操作:

    基本上,每个端点都应该实现:

    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”)

    而是启用IIS的WCF相关功能:

    此链接可能会有所帮助,谢谢。我试过了,但没用。好吧……但是如果没有一个答案真的有用,那么我应该选择最接近的一个?我已经编辑了你的标题。请看“”,其中的共识是“不,他们不应该”。谢谢。只是尝试了一下,但没有成功,客户端示例的链接已经失效。我尝试在我的web.config中添加跨域绑定,但没有成功。只需谷歌或在此处搜索JSONP-有大量的示例,例如:仅修复服务器端不起作用。此外,您可以显示您的WCF代码吗?除了允许在Web.Config中使用WebGet(根据上面的示例),您还需要使用正确的属性来修饰WCF方法。非常感谢您的帮助。我尝试了新设置,但也不起作用,但我还没有尝试json方法。我也更新了我的代码部分。终于!在使用JSONP(回调参数非常重要)之后,它工作了!!!!万分感谢!
    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");
        }