WebApi2请求的资源不支持post。

时间:2021-12-03 13:30:53

I've read a ton of similar posts that describe the same error message but they don't seem to match what i'm experiencing.

我读过很多类似的帖子,它们描述了相同的错误信息,但它们似乎与我所经历的不相符。

I have recently started using Web API and ripped all my MVC methods out where I was returning JSON etc, so MVC will just render the html and I will call down the models via ajax from my webapi controllers.

我最近开始使用Web API,并将所有MVC方法都从返回JSON的地方剥离出来,因此MVC只呈现html,我将通过webapi控制器调用ajax调用模型。

Here's the strange thing, I can GET and POST from my Home apiController (so I can login/signup etc) but I can only GET from an API Controller in an area I have created. I get a 405 (Method Not Allowed) even though its decorated and called the same way as other controller. I guess the routing is okay otherwise it wouldn't return my initial get?

奇怪的是,我可以从家里的apiController那里获取和发布(这样我就可以登录/注册等等),但是我只能从我创建的区域的API控制器中获取。我得到了一个405(不允许使用方法),尽管它的修饰和调用方式与其他控制器相同。我想路由是可以的,否则它不会返回初始get?

Routing

路由

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

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

Controller

控制器

 // Returns Model
 [HttpGet]
 public HttpResponseMessage SelectAgent()

 // The requested resource does not support http method 'POST'. 
 [HttpPost]
 public HttpResponseMessage SelectAgent(Guid id)

JQuery

JQuery

 // Works fine
    $.ajax({
            type: 'POST',
            url: '/api/Home/Login',
            headers: options.headers,
            contentType: "application/json; charset=utf-8",
            dataType: 'JSON',
            data: ko.toJSON(self.serverModel),
            success: function (response) {

   // Works fine
   $.getJSON("/api/Account/Users/SelectAgent", function (model) { ....

   // 405 
    $.ajax({
        type: 'POST',
        url: '/api/Account/Users/SelectAgent',
        headers: options.headers,
        contentType: "application/json; charset=utf-8",
        dataType: 'JSON',
        data: "{'id':'" + selectModel.agentId() + "'}",
        success: function (response) {....

data being passed seems fine (or at least it was for the MVC controller that it used to work with).

传递的数据看起来很好(或者至少是它以前使用的MVC控制器)。

I haven't modified the Home API Controller at all, I don't understand how I can post to that and not my other controller. Argh.

我还没有修改Home API控制器,我不知道如何将它发布到那个,而不是我的另一个控制器。啊。

Any pointers in the right direction would be awesome.

任何指向正确方向的指针都非常棒。

3 个解决方案

#1


12  

Web API is only looking at your querystring parameters for basic data types. Thus your post is just looking at the url of /api/Account/Users/SelectAgent when you are making your post. The data being submitted is not being considered when matching against the function, since you are not marking the Guid with a [FromBody] attribute. So the "Method Not Allowed" error is being returned because it is sending your POST request to your GET method (no params).

Web API只查看基本数据类型的querystring参数。因此,您的帖子只是在发布帖子时查看/api/Account/Users/SelectAgent的url。当与函数匹配时,不考虑提交的数据,因为您没有使用[FromBody]属性标记Guid。因此,“不允许的方法”错误将被返回,因为它将您的POST请求发送到您的GET方法(没有params)。

You can read more about this on asp.net:

你可以在asp.net中读到更多:

If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)

如果参数是“简单”类型,那么Web API将尝试从URI中获取值。简单类型包括。net基元类型(int, bool, double,等等)、TimeSpan、DateTime、Guid、decimal和string,以及任何类型的转换器,可以从字符串中进行转换。(稍后将详细介绍类型转换器。)

To fix this, try doing one of the following:

要解决这个问题,请尝试以下方法之一:

  1. Change the url that you are submitting to include the id in the querystring of the email

    更改要提交的url,以便在电子邮件的querystring中包含id

    url: '/api/Account/Users/SelectAgent?id=' + selectModel.agentId()

    url:“/ api /账户/用户/ SelectAgent吗?id = ' + selectModel.agentId()

  2. Change the Action signature to read the Id FromBody:

    将动作签名更改为读取Id FromBody:

    public HttpResponseMessage SelectAgent([FromBody]Guid id)

    公共HttpResponseMessage SelectAgent([FromBody]Guid id)

#2


3  

I know this is an old question, but this answer might help someone. Changing the Action signature to read the Id FromBody: did not work for me and I wonder how easy it will be passing the parameters to the querystring when you have a complex type with many fields/members.

我知道这是个老问题,但这个答案可能会对某些人有所帮助。更改动作签名以读取Id FromBody:对我来说没有作用,我想知道当您拥有多个字段/成员的复杂类型时,将参数传递给querystring是多么容易。

This problem is as a result of the fact that both traditional and verb-based routing cannot be used in the same ApiController. See this link. You can resolved this problem by adding an empty [Route] attribute to the POST action method. That is:-

这个问题是由于传统路由和基于普通路由不能在同一个ApiController中使用。看到这个链接。您可以通过向POST操作方法添加一个空的[Route]属性来解决这个问题。这是:

 [HttpPost]
 [Route]
 public HttpResponseMessage SelectAgent(Guid id)

#3


1  

When you have same Name for your post and get function, It routes to the Get function. Thats why you get this answer. Easiest way today is

当你的post和get函数有相同的名称时,它就会路由到get函数。这就是你得到这个答案的原因。今天的最容易的方法是

 [HttpPost]
 [Route("api/postagent", Name ="postagent")]
 public HttpResponseMessage SelectAgent(Guid id)

just define a route for your post function and on the client side post it with host + /api/postagent for example. you find more detailed information over this link.

只需为post函数定义一个路由,并在客户端使用host + /api/postagent进行post。您可以通过这个链接找到更详细的信息。

This is especially helpful if you create an api controller by generatin new controller. Predefined functions will have such structure as get and post method will have same route. you need to redefine one of them or both of them separate them.

如果您使用generatin new controller创建api控制器,这将非常有用。预定义的函数将具有这样的结构,如get和post方法将具有相同的路由。你需要重新定义其中的一个,或者两者都分开。

https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-names

https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2路由名称

#1


12  

Web API is only looking at your querystring parameters for basic data types. Thus your post is just looking at the url of /api/Account/Users/SelectAgent when you are making your post. The data being submitted is not being considered when matching against the function, since you are not marking the Guid with a [FromBody] attribute. So the "Method Not Allowed" error is being returned because it is sending your POST request to your GET method (no params).

Web API只查看基本数据类型的querystring参数。因此,您的帖子只是在发布帖子时查看/api/Account/Users/SelectAgent的url。当与函数匹配时,不考虑提交的数据,因为您没有使用[FromBody]属性标记Guid。因此,“不允许的方法”错误将被返回,因为它将您的POST请求发送到您的GET方法(没有params)。

You can read more about this on asp.net:

你可以在asp.net中读到更多:

If the parameter is a “simple” type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)

如果参数是“简单”类型,那么Web API将尝试从URI中获取值。简单类型包括。net基元类型(int, bool, double,等等)、TimeSpan、DateTime、Guid、decimal和string,以及任何类型的转换器,可以从字符串中进行转换。(稍后将详细介绍类型转换器。)

To fix this, try doing one of the following:

要解决这个问题,请尝试以下方法之一:

  1. Change the url that you are submitting to include the id in the querystring of the email

    更改要提交的url,以便在电子邮件的querystring中包含id

    url: '/api/Account/Users/SelectAgent?id=' + selectModel.agentId()

    url:“/ api /账户/用户/ SelectAgent吗?id = ' + selectModel.agentId()

  2. Change the Action signature to read the Id FromBody:

    将动作签名更改为读取Id FromBody:

    public HttpResponseMessage SelectAgent([FromBody]Guid id)

    公共HttpResponseMessage SelectAgent([FromBody]Guid id)

#2


3  

I know this is an old question, but this answer might help someone. Changing the Action signature to read the Id FromBody: did not work for me and I wonder how easy it will be passing the parameters to the querystring when you have a complex type with many fields/members.

我知道这是个老问题,但这个答案可能会对某些人有所帮助。更改动作签名以读取Id FromBody:对我来说没有作用,我想知道当您拥有多个字段/成员的复杂类型时,将参数传递给querystring是多么容易。

This problem is as a result of the fact that both traditional and verb-based routing cannot be used in the same ApiController. See this link. You can resolved this problem by adding an empty [Route] attribute to the POST action method. That is:-

这个问题是由于传统路由和基于普通路由不能在同一个ApiController中使用。看到这个链接。您可以通过向POST操作方法添加一个空的[Route]属性来解决这个问题。这是:

 [HttpPost]
 [Route]
 public HttpResponseMessage SelectAgent(Guid id)

#3


1  

When you have same Name for your post and get function, It routes to the Get function. Thats why you get this answer. Easiest way today is

当你的post和get函数有相同的名称时,它就会路由到get函数。这就是你得到这个答案的原因。今天的最容易的方法是

 [HttpPost]
 [Route("api/postagent", Name ="postagent")]
 public HttpResponseMessage SelectAgent(Guid id)

just define a route for your post function and on the client side post it with host + /api/postagent for example. you find more detailed information over this link.

只需为post函数定义一个路由,并在客户端使用host + /api/postagent进行post。您可以通过这个链接找到更详细的信息。

This is especially helpful if you create an api controller by generatin new controller. Predefined functions will have such structure as get and post method will have same route. you need to redefine one of them or both of them separate them.

如果您使用generatin new controller创建api控制器,这将非常有用。预定义的函数将具有这样的结构,如get和post方法将具有相同的路由。你需要重新定义其中的一个,或者两者都分开。

https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-names

https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2路由名称