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

时间:2022-08-22 10:07:01

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 WebAPI2上不允许的方法(OWIN)

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标头

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

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更新了我的代码以遵循基于令牌的身份验证

5 个解决方案

#1


10  

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

#2


4  

You might need to allow cors in your application for response headers. Below is sample for what I do in node.

您可能需要在应用程序中允许使用响应头的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');

This could help you. Thanks.

这可以帮到你。谢谢。

#3


2  

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. Problem is by default Postman does not post the Origin attribute, which is needed to test CORS. Chrome does block the Origin attribute by default, hence the request is not treated as if its coming from a different domain.

问题不在于角度。虽然你在Postman中得到了一个回应,但是这个请求中没有问题的问题并没有给你答案。问题是默认情况下Postman不会发布测试CORS所需的Origin属性。 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(打包应用程序),并使用其“请求拦截器切换开关”使其能够发送ORIGIN属性。

read here, section restricted header

在这里阅读,部分限制标题

below is the sample screen shot when you dont send the ORIGIN attributes

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

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

and the same request;s response in POSTMAN when you send the ORIGIN attribute

以及相同的请求;当您发送ORIGIN属性时,在POSTMAN中的响应

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

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. First enable CORS in web-api. To enable CORS globally use

回到你的案例,你没有在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);
        // ...
    }
}

-- 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()函数中的代码下方需要角色的角色。

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属性。我对这一部分不太确定,但根据我在Postman看到的回应,情况似乎如此。如果有人能够阐明Cors中的Origin属性,那将会很棒。

#4


1  

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/

#5


1  

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. Then there is easy way to do this in angular by setting $http provider default option.

要设置CORS,您始终需要在每次调用服务器时发送您的凭据。然后通过设置$ 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.

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

#1


10  

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

#2


4  

You might need to allow cors in your application for response headers. Below is sample for what I do in node.

您可能需要在应用程序中允许使用响应头的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');

This could help you. Thanks.

这可以帮到你。谢谢。

#3


2  

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. Problem is by default Postman does not post the Origin attribute, which is needed to test CORS. Chrome does block the Origin attribute by default, hence the request is not treated as if its coming from a different domain.

问题不在于角度。虽然你在Postman中得到了一个回应,但是这个请求中没有问题的问题并没有给你答案。问题是默认情况下Postman不会发布测试CORS所需的Origin属性。 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(打包应用程序),并使用其“请求拦截器切换开关”使其能够发送ORIGIN属性。

read here, section restricted header

在这里阅读,部分限制标题

below is the sample screen shot when you dont send the ORIGIN attributes

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

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

and the same request;s response in POSTMAN when you send the ORIGIN attribute

以及相同的请求;当您发送ORIGIN属性时,在POSTMAN中的响应

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

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. First enable CORS in web-api. To enable CORS globally use

回到你的案例,你没有在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);
        // ...
    }
}

-- 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()函数中的代码下方需要角色的角色。

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属性。我对这一部分不太确定,但根据我在Postman看到的回应,情况似乎如此。如果有人能够阐明Cors中的Origin属性,那将会很棒。

#4


1  

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/

#5


1  

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. Then there is easy way to do this in angular by setting $http provider default option.

要设置CORS,您始终需要在每次调用服务器时发送您的凭据。然后通过设置$ 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.

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