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

C# 为什么http get方法在asp.net web api中接受http post请求?,c#,asp.net-core,asp.net-core-webapi,asp.net-core-routing,C#,Asp.net Core,Asp.net Core Webapi,Asp.net Core Routing,我有一个HTTP-GET方法,如下所示 [Route("api/[controller]")] [ApiController] public class CityController : ControllerBase { public ActionResult Get(int id) { try { var city = new { CityName = "Gotham" }; return Ok(c

我有一个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"
}
现在我的问题是

既然它是一个GET,它应该接受一个职位吗? 它不应该返回405状态码吗?为什么不返回?至少我在期待 在这种情况下,如果我必须返回405,该怎么办? 既然它是一个GET,它应该接受一个职位吗

由于操作名和基于约定的路由,您假设它是get,但您可能会错误地认为控制器已被修饰为属性路由

[Route("api/[controller]")]
因此,如果进行匹配,则忽略基于约定的路由。请注意,PUT和DELETE

也应该在相同的操作上工作

它不应该返回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,该怎么办

属性路由就绪后,框架将为您完成这项工作,因此您无需再做其他事情

参考文献

混合路由:属性路由与传统路由 这两种路由系统的区别在于URL匹配路由模板后应用的流程。在常规路由中,匹配的路由值用于从所有常规路由动作的查找表中选择动作和控制器。在属性路由中,每个模板都已与一个操作关联,无需进一步查找

既然它是一个GET,它应该接受一个职位吗

由于操作名和基于约定的路由,您假设它是get,但您可能会错误地认为控制器已被修饰为属性路由

[Route("api/[controller]")]
因此,如果进行匹配,则忽略基于约定的路由。请注意,PUT和DELETE

也应该在相同的操作上工作

它不应该返回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,该怎么办

属性路由就绪后,框架将为您完成这项工作,因此您无需再做其他事情

参考文献

混合路由:属性路由与传统路由 这两种路由系统的区别在于URL匹配路由模板后应用的流程。在常规路由中,匹配的路由值用于从所有常规路由动作的查找表中选择动作和控制器。在属性路由中,每个模板都已与一个操作关联,无需进一步查找


谢谢你的回答,现在我明白了。我还注意到,添加[HttpGet]确实会阻止进行POST调用,但它返回404,这很好,但我不是专家,我认为405更合适谢谢你的回答,现在我明白了。我还注意到,添加[HttpGet]确实会阻止进行POST调用,但它返回404,这很好,但我不是专家,我认为405更合适