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

ASP.NET Core MVC修改控制器路由名称遇404错误求非Areas方案

ASP.NET Core MVC 自定义路由配置解决(不使用Areas)

需求说明

  • 访问UserController的Login方法时,URL显示为 https://localhost:7214/admin/login
  • 访问CustomerController的Index方法时,URL显示为 https://localhost:7214/customers/index
  • 不使用Areas特性

初始代码及问题

UserController.cs

[Route("admin")]
public class UserController : Controller
{
    [AllowAnonymous]
    public IActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

CustomerController.cs

[Route("customers")]
public class CustomerController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

Program.cs(初始配置)

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Admin}/{action=Login}/{id?}");

app.Run();

运行后出现404错误,后续修改Program.cs添加了Customer的路由配置:

app.MapControllerRoute(
    name: "customers",
    pattern: "customers/{action}/{id?}",
    defaults: new { controller = "Customer", action = "Index" }); 

此时CustomerController.Index可正常访问,但添加了[Route("test/export")]的Test方法仍报404:

public class CustomerController : Controller
{
    public IActionResult Index()  // 正常访问
    {
        return View();
    }

    [Route("test/export")]
    public IActionResult Test()  // 404错误
    {
        return View();
    }
}

问题根源

核心原因是混合使用了属性路由([Route]特性)和约定路由(MapControllerRoute),两种路由机制的匹配逻辑冲突,导致部分请求无法被正确解析:

  1. 初始配置中,UserController仅标注了控制器级[Route("admin")],未指定方法级路由,无法匹配admin/login路径;同时约定路由默认指向Admin控制器(实际不存在),双重匹配失败引发404。
  2. 修改后的配置中,CustomerController.Index通过约定路由匹配成功,但Test方法的属性路由test/export是独立路径,未被任何路由规则覆盖,且与控制器的约定路由前缀不兼容,导致404。

解决方案

方案一:统一使用属性路由(灵活可控)

删除所有约定路由配置,仅通过[Route]特性定义路由规则:

修改UserController.cs

[Route("admin")]
public class UserController : Controller
{
    [AllowAnonymous]
    [Route("login")] // 组合为 admin/login
    public IActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

修改CustomerController.cs

[Route("customers")]
public class CustomerController : Controller
{
    [Route("index")] // 组合为 customers/index;若改为[Route("")],则 customers/ 也可访问Index
    public IActionResult Index()
    {
        return View();
    }

    // 若希望URL为 customers/test/export,使用相对路由(相对于控制器前缀)
    [Route("test/export")]
    public IActionResult Test()
    {
        return View();
    }

    // 若希望URL为独立的 /test/export,使用~前缀声明绝对路由
    // [Route("~/test/export")]
    // public IActionResult Test()
    // {
    //     return View();
    // }
}

修改Program.cs

// 启用属性路由支持
app.MapControllers();

// 移除原有的MapControllerRoute配置,避免冲突
app.Run();

方案二:统一使用约定路由(规则集中管理)

删除所有[Route]特性,通过MapControllerRoute集中配置路由规则:

修改UserController.cs

public class UserController : Controller
{
    [AllowAnonymous]
    public IActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

修改CustomerController.cs

public class CustomerController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Test()
    {
        return View();
    }
}

修改Program.cs

// 配置User路由:admin/login 映射到UserController.Login
app.MapControllerRoute(
    name: "admin",
    pattern: "admin/{action=Login}/{id?}",
    defaults: new { controller = "User" });

// 配置Customer路由:customers/index 映射到CustomerController.Index,其他方法如customers/test
app.MapControllerRoute(
    name: "customers",
    pattern: "customers/{action=Index}/{id?}",
    defaults: new { controller = "Customer" });

// 可选:配置Test方法的独立路由 /test/export
app.MapControllerRoute(
    name: "test-export",
    pattern: "test/export",
    defaults: new { controller = "Customer", action = "Test" });

// 可选:保留默认路由作为兜底
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

效果验证

  • 方案一:访问/admin/login进入UserController.Login,/customers/index进入CustomerController.Index,/customers/test/export(或/test/export,根据配置)进入CustomerController.Test。
  • 方案二:访问/admin/login进入UserController.Login,/customers/index进入CustomerController.Index,/customers/test或/test/export(根据配置)进入CustomerController.Test。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:36:53