WebAPI2 (OWIN) 上不允许使用 405 方法

405 Method Not Allowed on WebAPI2 (OWIN)

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

网络API和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 示例站点正在发送相同的请求 headers,但能够获得 Access-Control-Allow-XXX headers

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

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

请参阅这篇文章以获得对 CORS: http://www.html5rocks.com/en/tutorials/cors/

的很好解释

我认为您的 API 控制器上缺少注释,您应该在 API 控制器上添加注释,如

[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 的配置阶段执行此操作。

代码

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

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

另请参阅 this post。有些什么同样的问题。

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

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

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

您可能需要在您的应用程序中允许 cors 以进行响应 headers。下面是我在节点中所做的示例。

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');

这可以帮助你。谢谢

问题不在于 angular。尽管您在 Postman 中得到响应,但在 angular 中请求没有给您响应不是问题。问题是默认情况下 Postman 没有 post Origin attribute,这是测试 CORS 所需要的。 Chrome 默认情况下会阻止 Origin 属性,因此请求不会被视为来自不同的域。

那么如何在Postman中测试CORS

您需要一个具有相同名称 POSTMAN - Rest Client (Packaged App) 的不同 chrome 扩展,并使用其 'Request Interceptor toggle switch' 使其能够发送 ORIGIN 属性。

read here,节 restricted header

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

和相同的请求;发送 ORIGIN 属性时在 POSTMAN 中的响应

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

我希望这也能回答您关于

的问题

BitOfTech sample site, is sending the same request headers, but is able to get the Access-Control-Allow-XXX headers"

网页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);
        // ...
    }
}

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

Angular部分

您首先需要确保 CORS 在 POSTMAN 中正常工作,然后尝试在 angular.

中访问 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 中看到的回复,情况似乎是这样。如果有人能阐明 Origin attribute 在 Cors.

中的角色,那就太好了