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

ASP.NET Core如何配置Api子文件夹路由分离Api与View控制器

.NET 6 ASP.NET Core Api子目录控制器路由404修复方案

改造背景

针对大体量.NET 6 ASP.NET Core项目做非全量重构的渐进式改造,目标为分离数据逻辑与视图逻辑:

  • 将视图控制器中混杂的大量数据端点迁移至独立控制器
  • 缩减视图控制器代码体积
  • 抽离多个视图控制器间的共享数据端点
  • 统一数据请求访问专属API端点,不再走视图控制器绑定的根路由
    期望实现的目录结构:
Controllers
├─ Api
│  └─ Data1Controller
└─ View1Controller

问题复现

尝试使用Areas功能做路由隔离,Program.cs中路由配置代码如下:

app.UseRouting();
app.MapAreaControllerRoute("Api", "Api", "Api/{controller}/{action}/{id?}");
app.MapDefaultControllerRoute();

已为Api目录下的控制器标记[Area("Api")]特性,但访问/api/data路径时返回404错误。

故障原因

404是两个配置不匹配共同导致的:

  1. ASP.NET Core Area功能默认扫描的控制器路径为根目录/Areas/<Area名称>/Controllers,当前将Api控制器放在Controllers/Api目录下,不在默认扫描范围内,路由系统无法匹配到对应控制器
  2. 若数据接口控制器标记了[ApiController]特性,该特性默认优先启用属性路由,手写的传统约定路由(MapAreaControllerRoute、MapDefaultControllerRoute)对这类控制器默认不生效

推荐解决方案(适配渐进式改造场景,侵入性最低)

不需要使用Areas功能,通过自定义控制器约定统一给Api子目录下的控制器注入路由前缀,完全保留现有目录结构,不影响原有视图控制器的路由规则。

  1. 清空之前写的Area相关路由配置,在Program.cs的服务注册阶段添加自定义控制器约定:
builder.Services.AddControllersWithViews(options =>
{
    // 为Api子目录下的控制器统一配置路由前缀
    options.Conventions.Add(new ApiNamespaceRouteConvention());
});
  1. 在项目中添加自定义约定实现类,可直接放在Program.cs同级命名空间下:
public class ApiNamespaceRouteConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        // 识别命名空间以Controllers.Api结尾的控制器(对应Controllers/Api目录结构)
        if (controller.ControllerType.Namespace?.EndsWith("Controllers.Api") == true)
        {
            // 统一注入路由模板:前缀为api,匹配控制器名、Action名,可选id参数
            controller.Selectors.Add(new SelectorModel
            {
                AttributeRouteModel = new AttributeRouteModel
                {
                    Template = "api/[controller]/[action]/{id?}"
                }
            });
        }
    }
}

配置完成后,Controllers/Api目录下的所有控制器自动匹配/api/[controller]/[action]路径,外层普通视图控制器仍然走默认的/[controller]/[action]路由,完全兼容原有逻辑,不需要批量修改现有控制器代码。

注意:如果Api控制器标记了[ApiController]特性,该方案同样生效,不需要额外调整。

备选方案(坚持使用Area功能的修正方式)

如果一定要使用Areas实现路由隔离,需要做两处修正:

  1. 调整控制器搜索规则,让框架能识别Controllers/Api目录下的Area控制器,在服务注册阶段添加配置:
builder.Services.AddControllersWithViews()
    .AddRazorOptions(options =>
    {
        // 仅当Api区域下有视图需求时需要配置视图搜索路径,纯接口可跳过
        options.AreaViewLocationFormats.Add("/Controllers/Api/{1}/{0}.cshtml");
    });
  1. 确保Api控制器同时标记正确的特性:
[Area("Api")]
[ApiController]
public class Data1Controller : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok();
}

该方案后续新增全局过滤器、模型绑定时需要额外做命名空间判断,侵入性比推荐方案高,不适合渐进式改造场景。

验证方式

配置完成后重启应用,访问/api/data1/youraction路径即可命中对应Api控制器的接口,原有视图控制器的访问路径不受影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:54:25