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

ASP.NET Core MVC中如何在控制器内创建路由分组?

在ASP.NET Core MVC中实现指定API路由分组的解决方案

你之前尝试用ApiController内部嵌套子类的方式行不通,原因有两个:

  • ASP.NET Core默认不会将嵌套子类识别为独立的API控制器,所以路由不会被注册到路由系统中
  • 嵌套类无法自动获取父类的依赖实例(比如myService),DI容器不会为嵌套类注入依赖

下面是两种可行的实现方案,都能满足你需要的路由规则,且Swagger能正常识别:

方案一:独立控制器+路由前缀(推荐)

创建多个顶级控制器,通过[Route]特性设置统一的路由前缀,同时依赖注入可以正常工作:

1. 注册依赖服务

先确保你的MyService已经在DI容器中注册:

builder.Services.AddScoped<MyService>();

2. 实现Speak控制器(对应api/speak)

[ApiController]
[Route("api/speak")]
public class SpeakController : ControllerBase
{
    private readonly MyService _myService;

    // 构造函数注入依赖
    public SpeakController(MyService myService)
    {
        _myService = myService;
    }

    [HttpGet]
    public IActionResult GetSpeak()
    {
        return Ok($"Speak endpoint: {_myService.GetMessage()}");
    }
}

3. 实现Dance控制器(对应api/dance/tango、api/dance/salsa)

[ApiController]
[Route("api/dance")]
public class DanceController : ControllerBase
{
    private readonly MyService _myService;

    public DanceController(MyService myService)
    {
        _myService = myService;
    }

    [HttpGet("tango")]
    public IActionResult Tango()
    {
        return Ok($"Tango: {_myService.GetMessage()}");
    }

    [HttpGet("salsa")]
    public IActionResult Salsa()
    {
        return Ok($"Salsa: {_myService.GetMessage()}");
    }
}

4. 实现Sing控制器(对应api/sing/song、api/sing/tune)

[ApiController]
[Route("api/sing")]
public class SingController : ControllerBase
{
    private readonly MyService _myService;

    public SingController(MyService myService)
    {
        _myService = myService;
    }

    [HttpGet("song")]
    public IActionResult Song()
    {
        return Ok($"Song: {_myService.GetMessage()}");
    }

    [HttpGet("tune")]
    public IActionResult Tune()
    {
        return Ok($"Tune: {_myService.GetMessage()}");
    }
}

这种方式结构清晰,DI自动注入依赖,Swagger会自动扫描所有控制器并显示对应的路由。

方案二:使用区域(Areas)实现模块化分组

如果你的API需要更严格的模块化划分,可以用ASP.NET Core的区域特性:

1. 创建区域结构

在项目中创建如下目录结构:

Areas/
├─ Dance/
│  ├─ Controllers/
│  │  └─ DanceController.cs
├─ Sing/
│  ├─ Controllers/
│  │  └─ SingController.cs

2. 配置区域路由

在Program.cs中添加区域路由规则:

app.MapControllerRoute(
    name: "areaApi",
    pattern: "api/{area}/{action}",
    defaults: new { controller = "{area}" });

3. 实现区域内的控制器

以Dance控制器为例:

[ApiController]
[Area("dance")]
public class DanceController : ControllerBase
{
    private readonly MyService _myService;

    public DanceController(MyService myService)
    {
        _myService = myService;
    }

    public IActionResult Tango()
    {
        return Ok($"Tango: {_myService.GetMessage()}");
    }

    public IActionResult Salsa()
    {
        return Ok($"Salsa: {_myService.GetMessage()}");
    }
}

这种方式适合大型项目的模块化管理,同样能满足路由要求,Swagger也能正常识别。

为什么嵌套子类的方式不推荐

即使你手动将嵌套子类注册为控制器(通过builder.Services.AddControllers().AddApplicationPart(...)),也需要手动处理依赖传递,而且Swagger需要额外配置才能识别这些嵌套控制器,步骤繁琐且维护成本高,远不如上述两种方案简洁可靠。

内容的提问来源于stack exchange,提问作者Skye TheFox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:42:52