首页 > 解决方案 > 为什么http get方法在asp.net web api中接受http post请求?

问题描述

我有一种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. 因为它是 a GET,它应该接受 aPOST吗?
  2. 它不应该返回 405 状态码,为什么不返回?(至少我期待)
  3. 在这种情况下,如果我必须返回 405 怎么办?

标签: c#asp.net-coreasp.net-core-webapiasp.net-core-routing

解决方案


由于它是 GET,它应该接受 POST 吗?

虽然由于动作名称和基于约定的路由而假设它是一个 get,但您会误认为控制器已被修饰为属性路由。

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

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

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

也应该在相同的动作上工作。

它不应该返回 405 状态码,为什么不返回?(至少我期待)

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

[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 错误,因为路径匹配但方法不匹配。

在这种情况下,如果我必须返回 405 怎么办?

有了属性路由,框架将为您完成,因此您无需再做任何事情。

参考路由到 ASP.NET Core 中的控制器操作

混合路由:属性路由与常规路由

这两种路由系统的区别在于 URL 与路由模板匹配后应用的过程。在常规路由中,来自匹配的路由值用于从所有常规路由动作的查找表中选择动作和控制器。在属性路由中,每个模板已经与一个动作相关联,不需要进一步查找。


推荐阅读