【问题标题】:405 Method Not Allowed on WebAPI2 (OWIN)WebAPI2 (OWIN) 上不允许使用 405 方法
【发布时间】:2015-03-16 19:30:57
【问题描述】:

我正在为我的 API 设置一个 WebAPI 端点,但是我无法让我的 AngularJS 调用对我的 PostRegister 方法起作用。

webAPI 和 Angular 位于不同的站点。

在 Startup.cs 我有:

    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);

        var config = new HttpConfiguration();

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

    private void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString(Paths.TokenPath),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = Kernel.Get<IOAuthAuthorizationServerProvider>()
        };
        app.UseOAuthAuthorizationServer(oAuthServerOptions); 

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    }

然后在控制器上,我的方法设置为允许匿名:

    [AllowAnonymous]
    public bool PostRegister(UserSignupForm form)
    {
        ...
    }

我还更新了 web.config:

 <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

在 Angular 方面,我做了一个简单的 $http.post 调用:

    saveRegistration: function (registration) {
        return $http.post(baseUrl + '/api/signup/register', registration).then(function (response) {
            return response;
        });
    }

使用 Postman 进行调用时,我得到了成功的响应,但是当从 Angular 进行相同的调用时,我得到了 405 错误。

BitOfTech 示例站点,正在发送相同的请求标头,但能够获取 Access-Control-Allow-XXX 标头

我已更新我的代码以关注 Token Based Authentication using ASP.NET Web API 2, Owin, and Identity

【问题讨论】:

  • 你能在你的控制器中发布相关的路由代码吗?
  • 顺便说一句,您的代码看起来与您链接的文章根本不一样,您的 PostRegister() 函数的签名与网站上代码中的任何函数完全不同,并且不似乎也与 angular.js $http.post 方法的签名相匹配。
  • 其他方法有用吗?如果在 PostRegister() 上方设置 [HttpPost] 属性是否有帮助? (以防你的路线搞砸了......)
  • @AndrewCounts,我已经开始了我的项目,但无法让它工作,所以我开始对其进行调整,使其类似于我链接到的文章。
  • 我怀疑您是否在邮递员响应中获得了访问控制标头。要在邮递员响应中获取这些属性,您需要添加源属性。我也没有看到为 webapi 启用了 CORS

标签: angularjs asp.net-web-api cors asp.net-web-api2 owin


【解决方案1】:

我最近有类似的问题。我为飞行前OPTIONS 请求添加了控制器处理程序,它解决了问题。

[AllowAnonymous]
[Route("Register")]
[AcceptVerbs("OPTIONS")]
public async Task<IHttpActionResult> Register()
{
    return Ok();
}

【讨论】:

  • CorsOptions.AllowAll 应该接受所有动词,不是吗?来自 XML cmets “允许所有标头、所有方法、任何来源并支持凭据的策略”
【解决方案2】:

您可能需要在应用程序中允许响应标头使用 cors。以下是我在节点中所做的示例。

res.header('Access-Control-Allow-Origin', '*');

res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS"); 

res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

这可以帮助你。谢谢。

【讨论】:

    【解决方案3】:

    问题不在于角度。尽管您在Postman 中得到了响应,但从角度来看,请求没有给您响应并不是问题。问题是默认情况下 Postman 不会发布测试 CORS 所需的 Origin attribute。 Chrome 默认会阻止 Origin 属性,因此不会将请求视为来自不同域。

    那么如何在 Postman 中测试 CORS

    您需要一个具有相同名称 POSTMAN - Rest Client (Packaged App) 的不同 chrome 扩展程序,并使用其“请求拦截器切换开关”使其能够发送 ORIGIN 属性。

    read here,部分restricted header

    以下是不发送 ORIGIN 属性时的示例屏幕截图

    当您发送 ORIGIN 属性时,POSTMAN 中的响应相同

    所以如果你看到,当你添加原点时,只有当你得到 ACCESS-CONTROL-* 属性作为响应时。

    我希望这也能回答您关于

    的问题

    BitOfTech 示例站点发送相同的请求标头,但 能够获取 Access-Control-Allow-XXX 标头”

    Web API 部分

    回到您的案例,您没有在 web-api 中启用 CORS。首先在 web-api 中启用 CORS。要在全球范围内启用 CORS,请使用

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var cors = new EnableCorsAttribute("www.example.com", "*", "*");
            config.EnableCors(cors);
            // ...
        }
    }
    

    -- 你可以在网络上找到很多关于如何在控制器级别等添加它的资源。

    角部分

    您首先需要确保 CORS 在 POSTMAN 中工作,然后尝试以角度访问该 url。

    要在 Angular 中启用 cors,您需要在 app.config() 函数中使用以下代码。

    myApp.config(function($httpProvider) {
      $httpProvider.defaults.useXDomain = true;
      delete $httpProvider.defaults.headers.common['X-Requested-With'];
    });
    

    注意:专家级

    Origin attributes is needed to test CORS.这部分我不太确定,但根据我在 Postman 中看到的回复,情况似乎如此。如果有人能阐明 Cors 中 Origin attribute 的角色,那就太好了。

    【讨论】:

      【解决方案4】:

      这听起来像是一个跨域问题。您应该安装 Fiddler 并检查 405 响应是否是由浏览器在调用不同来源的资源时发出的飞行前请求(OPTIONS 动词)引起的。

      有关CORS的详细解释,请参阅这篇文章:http://www.html5rocks.com/en/tutorials/cors/

      【讨论】:

      【解决方案5】:

      我认为您的 API Controller 上缺少注释,您应该在 APIController 上添加注释

      [RoutePrefix("api/signup")]
      

      否则你的WebApiConfig 应该有如下定义的路由

      public static class WebApiConfig
          {
              public static void Register(HttpConfiguration config)
              {
                  config.Routes.MapHttpRoute(
                      name: "DefaultApi",
                      routeTemplate: "api/{controller}/{id}",
                      defaults: new { id = RouteParameter.Optional }
                  );
              }
          }
      

      要设置 CORS,您始终需要在每次调用服务器时发送您的凭据。 然后,通过设置 $http 提供程序默认选项,可以轻松地以角度方式执行此操作。

      您可以在 angular 的配置阶段执行此操作。

      代码

        angular.module('myApp',[])
          .config([
              '$httpProvider',
              function($httpProvider) {
                  $httpProvider.defaults.withCredentials = true;
              }
          ]);
      

      以上设置将在每个 $http 调用中添加凭据。

      另请参阅this 帖子。有些什么相同的问题。

      这可能有助于解决您的问题。 谢谢。

      【讨论】:

        猜你喜欢
        • 2015-04-11
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 2012-06-29
        • 2013-03-13
        相关资源
        最近更新 更多