为什么 http get 方法在 asp.net web api 中接受 http post 请求?

Why does an http get method accepts http post request in asp.net web api?

我有一个 HTTP-GET 方法,如下所示

[Route("api/[controller]")]
[ApiController]
public class CityController : ControllerBase
{
    public ActionResult Get(int id)
    {
        try
        {
            var city = new { CityName = "Gotham" };
            return Ok(city);
        }
        catch(Exception ex)
        {
            return StatusCode(500);
        }
    }
}

对于这两种类型的请求

要求:

GET http://localhost:49915/api/city
POST http://localhost:49915/api/city

回复:

status: 200 OK
-------------------
{
    "cityName": "Gotham"
}

现在我的问题是,

  1. 因为它是 GET,它应该接受 POST 吗?
  2. 它不应该 return 一个 405 状态代码,为什么不呢? (至少我在期待)
  3. 在这种情况下,如果我必须return 405 怎么办?

As it is a GET, should it supposed to accept a POST?

虽然您因为操作名称和基于约定的路由而假设它是一个 get,但您会误以为控制器已针对属性路由进行了修饰。

[Route("api/[controller]")]

因此如果匹配则忽略基于约定的路由。请注意 PUTDELETE

PUT http://localhost:49915/api/city
DELETE http://localhost:49915/api/city

同样的动作也应该起作用。

Shouldn't it return a 405 status code and Why it does not? (at least I'm expecting)

该操作在设计上与两个调用匹配,因为没有为该操作指定指令。

[Route("api/[controller]")]
[ApiController]
public class CityController : ControllerBase {
    // GET api/city?id=2 //Note id would be optional as a query variable.
    [HttpGet]
    public ActionResult Get(int id) {
        try {
            var city = new { CityName = "Gotham" };
            return Ok(city);
        } catch(Exception ex) {
            return StatusCode(500);
        }
    }
}

现在有了 HttpGet,如果

POST http://localhost:49915/api/city

或者其他HTTP方法完成后,你会得到405错误,因为路径匹配但方法不匹配。

In such case, if I have to return 405 what to be done?

属性路由到位后,框架会为您完成,因此您无需再做任何事情。

引用Routing to controller actions in ASP.NET Core

Mixed routing: Attribute routing vs conventional routing

What distinguishes the two types of routing systems is the process applied after a URL matches a route template. In conventional routing, the route values from the match are used to choose the action and controller from a lookup table of all conventional routed actions. In attribute routing, each template is already associated with an action, and no further lookup is needed.