ASP.NET Core Web API路由规则疑问:控制器内请求路由机制解析
ASP.NET Core Web API 路由规则详解
一、无[Route]特性时的默认约定路由
ASP.NET Core Web API早期版本(或未配置属性路由的项目)会采用约定路由,一般在Program.cs里做如下配置:
app.MapControllerRoute( name: "default", pattern: "api/{controller}/{action}/{id?}" );
这套规则的核心逻辑:
{controller}:自动匹配控制器名称去掉Controller后缀,比如UsersController对应Users{action}:匹配方法名,但有个关键的HTTP方法前缀规则:- 方法名以
Get/Post/Put/Delete开头时,会自动绑定对应HTTP请求方法 - 比如
Get(int id)会匹配GET /api/Users/{id}(你提到的users<id>应该是users/{id}的笔误)
- 方法名以
二、方法命名与路由的关联逻辑
1. 标准HTTP前缀方法
如果方法名以Get/Post等HTTP动词开头,约定路由会自动处理:
- 绑定对应的HTTP请求方法
- 方法名去掉前缀后的部分作为路由的
action段(如果有)
举几个例子: Get()→ 匹配GET /api/UsersGet(int id)→ 匹配GET /api/Users/{id}PostUser(User model)→ 匹配POST /api/Users/PostUser
2. 非标准命名的方法
像你提到的GetWidgetInfo(int widgetId),在约定路由模式下:
- 因为方法名以
Get开头,依然绑定GET请求 - 完整路由是
GET /api/Users/GetWidgetInfo/{widgetId} - 如果想让路由里的占位符和参数名不一致,可以用
[FromRoute]显式指定:
GetWidgetInfo([FromRoute(Name = "id")] int widgetId)
这样就能匹配GET /api/Users/GetWidgetInfo/{id}
三、无占位符的[Route]特性用法
如果控制器或方法上用了[Route]但没加占位符,属于硬编码路由,比如:
[Route("api/users")] public class UsersController : ControllerBase { [Route("getwidgetinfo")] public IActionResult GetWidgetInfo(int widgetId) { // ... } }
这时参数会以QueryString形式传递,匹配GET /api/users/getwidgetinfo?widgetId=123;如果要把参数放到路由路径里,需要加占位符:
[Route("getwidgetinfo/{widgetId}")] public IActionResult GetWidgetInfo(int widgetId)
这样就匹配GET /api/users/getwidgetinfo/123
四、新版.NET Core的路由变化
ASP.NET Core 3.0+更推荐用属性路由(搭配[ApiController]),约定路由虽然仍支持,但显式定义路由更清晰,比如:
[ApiController] [Route("api/[controller]")] public class UsersController : ControllerBase { // 匹配 GET /api/Users/{id} [HttpGet("{id}")] public IActionResult Get(int id) { // ... } // 匹配 GET /api/Users/widget/{widgetId} [HttpGet("widget/{widgetId}")] public IActionResult GetWidgetInfo(int widgetId) { // ... } }
这里的[controller]是占位符,自动替换为控制器名称去掉Controller后缀;[HttpGet("{id}")]里的{id}和方法参数名直接绑定,不再依赖方法命名的约定,可读性更强。
内容的提问来源于stack exchange,提问作者msmith1114
相关产品推荐
相关产品推荐

