简体   繁体   English

405 WebAPI2上不允许的方法(OWIN)

[英]405 Method Not Allowed on WebAPI2 (OWIN)

I am setting up a WebAPI endpoint for my API, but am having trouble getting my AngularJS calls to my PostRegister method to work. 我正在为我的API设置一个WebAPI端点,但是我无法使用我的PostRegister方法调用AngularJS。

The webAPI and Angular are on separate sites. webAPI和Angular位于不同的站点上。

On the Startup.cs I have: 在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);
    }

Then on the controller, I have my method that is set to allow anonymous: 然后在控制器上,我的方法被设置为允许匿名:

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

I've also updated the web.config: 我还更新了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>

On the Angular side, I make a simple $http.post call: 在Angular方面,我做了一个简单的$ http.post调用:

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

When making the call using Postman, I get a successful response, but when doing the same call from Angular, I get the 405 error. 当使用Postman进行调用时,我得到了一个成功的响应,但是当从Angular执行相同的调用时,我得到405错误。

405方法不允许

BitOfTech sample site, is sending the same request headers, but is able to get the Access-Control-Allow-XXX headers BitOfTech示例站点正在发送相同的请求标头,但能够获取Access-Control-Allow-XXX标头

在此输入图像描述

I've updated my code to follow Token Based Authentication using ASP.NET Web API 2, Owin, and Identity 我已经使用ASP.NET Web API 2,Owin和Identity更新了我的代码以遵循基于令牌的身份验证

I had similar issue recently. 我最近有类似的问题。 I added controller handler for the pre-flight OPTIONS request and it solved the problem. 我为飞行前OPTIONS请求添加了控制器处理程序,它解决了问题。

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

You might need to allow cors in your application for response headers. 您可能需要在应用程序中允许使用响应头的cors。 Below is sample for what I do in node. 以下是我在节点中所做的示例。

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

This could help you. 这可以帮到你。 Thanks. 谢谢。

The problem is not with the angular. 问题不在于角度。 Though you get a response in Postman , its not problem in angular that request is not giving you the response. 虽然你在Postman中得到了一个回应,但是角度问题并没有给你带来回应。 Problem is by default Postman does not post the Origin attribute , which is needed to test CORS. 问题是默认情况下Postman不会发布测试CORS所需的Origin attribute Chrome does block the Origin attribute by default, hence the request is not treated as if its coming from a different domain. Chrome默认会阻止Origin属性,因此请求不会被视为来自其他域。

So how to test CORS in Postman 那么如何在Postman中测试CORS

you would need a different chrome extension with same name POSTMAN - Rest Client (Packaged App) , and use its 'Request Interceptor toggle switch' to enable it to send the ORIGIN attribute. 你需要一个具有相同名称的不同chrome扩展名POSTMAN - Rest Client(打包应用程序) ,并使用它的'Request Interceptor切换开关'来启用它来发送ORIGIN属性。

read here , section restricted header 在这里阅读 ,部分restricted header

below is the sample screen shot when you dont send the ORIGIN attributes 下面是不发送ORIGIN属性时的示例屏幕截图

没有原始

and the same request;s response in POSTMAN when you send the ORIGIN attribute 以及相同的请求;当您发送ORIGIN属性时,在POSTMAN中的响应

与起源

so if you see, when you add origin, that only when you get the ACCESS-CONTROL-* attributes in response. 因此,如果您看到,当您添加原点时,只有在您获得ACCESS-CONTROL- *属性作为响应时。

I hope this also answer your query about 我希望这也回答你的问题

BitOfTech sample site, is sending the same request headers, but is able to get the Access-Control-Allow-XXX headers" BitOfTech示例站点,正在发送相同的请求标头,但能够获取Access-Control-Allow-XXX标头“

Web Api Part Web Api部分

Coming back to your case, you do not have CORS enabled in web-api. 回到你的案例,你没有在web-api中启用CORS。 First enable CORS in web-api. 首先在web-api中启用CORS。 To enable CORS globally use 启用CORS全球使用

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

-- you can find lot of resources around net on how to add it on controller level etc. - 你可以在网上找到很多关于如何在控制器级别添加它的资源等。

Angular Part 角部

you first need to make sure that the CORS is working in POSTMAN and then try to access that url in angular. 首先需要确保CORS在POSTMAN中工作,然后尝试以角度访问该URL。

to enable cors in angular you need below code in your app.config() function. 要在你的app.config()函数中的代码下面启用角度的cors。

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

Note : For the Experts 注意:专家

Origin attributes is needed to test CORS. I am not very sure on this part, but seems like the case as per the response I see in Postman. 我对这一部分不太确定,但根据我在邮差中看到的回应,情况似乎如此。 It would be great if anyone can shed light on the role Origin attribute in Cors. 如果有人能够阐明Cors中的Origin attribute ,那将会很棒。

This sounds like a cross-origin issue. 这听起来像是一个跨领域的问题。 You should install Fiddler and check if the 405 response is caused by the pre-flight request (OPTIONS verb) that is issued by the browser when you're calling a resource on a different origin. 您应该安装Fiddler并检查405响应是否是由您在调用其他来源的资源时由浏览器发出的飞行前请求(OPTIONS动词)引起的。

See this article for a nice explanation of CORS : http://www.html5rocks.com/en/tutorials/cors/ 有关CORS的详细解释,请参阅此文章: http//www.html5rocks.com/en/tutorials/cors/

I believe you are missing annotation on your API Controller, you should add annotation on APIController as 我相信你在API控制器上缺少注释,你应该在APIController上添加注释

[RoutePrefix("api/signup")]

Otherwise your WebApiConfig should be have route define like Below 否则,您的WebApiConfig应该具有类似于Below的路由定义

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

And to setup CORS you always need to send your credential on every single call to server. 要设置CORS,您始终需要在每次调用服务器时发送您的凭据。 Then there is easy way to do this in angular by setting $http provider default option. 然后通过设置$ http provider default选项,可以通过简单的方法在角度中执行此操作。

You can do this at config phase of angular. 您可以在角度的配置阶段执行此操作。

CODE

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

Above setting will add credential in each $http call. 以上设置将在每个$ http调用中添加凭据。

Also refer this post. 也请参考这篇文章。 Some what the same problem. 有些什么相同的问题。

This may help to solve your problem. 这可能有助于解决您的问题。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM