You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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/Users
  • Get(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:24