ASP.NET MVC路由到没有区域的子目录

ASP.NET MVC Routing to sub directories without area

我已经将我的项目重新组织成一个更符合逻辑的层次结构:

-Controllers  
  -Accounts  
    -CustomersController  
  -Setup  
    -SystemDefaultsController
    -SettingsController
  -HomeController

目前,我正试图设置我的 URLs 来匹配这个结构。所以有效的例子 URLs 将是:

localhost:1234/Home/Index
localhost:1234/Setup/SystemDefaults/Index
localhost:1234/Setup/Settings/Index
localhost:1234/CustomerAccounts/Index

所以我在RouteConfig.cs中的默认路由之上添加了一条路由:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapMvcAttributeRoutes();

    //AreaRegistration.RegisterAllAreas();

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Setup",
        url: "Setup/{controller}/{action}/{id}",
        defaults: new { controller = "Setup", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { "MVCWeb.Controllers.Setup" }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { "MVCWeb.Controllers" }
    );
}

这确实使上面的 URL 起作用,但它没有限制,所以当我希望它们无效时,这些 URL 起作用:

localhost:1234/Setup/CustomerAccounts/Index localhost:1234/SystemDefaults/Index

此外,由于设置路由匹配所有内容,如果我执行以下任一操作:

@Html.ActionLink("Customer Accounts", "Index", "CustomerAccounts")
@Url.Action("Index", "CustomerAccounts")

它将 URL 生成为 /Setup/CustomerAccounts/Index 而不是 /CustomerAccounts/Index

有没有办法在不使用区域的情况下完成此操作,同时仍在路线 URL 中使用 {controller}?或者我是否必须在“设置”下专门为每个控制器添加一条路由?

您是否曾经评估过 Attribute Routing in MVC 5? It seems like you're starting a new project, so this could be a good new start. With the [RoutePrefix] attribute,您可能可以轻松地执行您想要实现的目标:

[RoutePrefix("accounts")]
public class CustomersController : Controller
{
    // ...
}

我们还没有使用属性路由,所以我不能根据自己的经验来谈,但它看起来非常灵活和有前途。

更新

  1. 我为您创建了一个 GIST,我在其中解释了如何验证您的属性,不是在编译期间,而是通过单元测试。这是为 MS 测试设计的简单代码片段。验证的可能性非常广泛。

  2. 自定义逻辑我们可以添加到自定义 RoutePrefixAttribute?例如,RoutePrefixAttribute 允许将字符串作为参数。您可以重写它以仅允许特定的 Enum 作为参数,它仅列出可能的值,并在内部设置 Prefix 字符串。