【问题标题】:ASP.NET MVC Routing to sub directories without areaASP.NET MVC 路由到无区域的子目录
【发布时间】:2018-05-20 13:03:58
【问题描述】:

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

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

目前,我只是尝试设置我的 URL 以匹配此结构。因此,有效的示例 URL 将是:

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 无效时,这些 URL 工作:

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

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

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

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

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

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-5 routes url-routing


    【解决方案1】:

    你评价过Attribute Routing in MVC 5吗?看起来你正在开始一个新项目,所以这可能是一个很好的新开始。使用[RoutePrefix] attribute,您可能可以轻松实现您想要实现的目标:

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

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

    更新

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

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

    【讨论】:

    • 我实际上只是在考虑这一点。我在属性路由方面经历过的一件事是很难跟踪。例如,如果有人在处理 URL 时输入了错误的路由,那么当您的路由在整个地方都被定义为属性而不是在单个位置时,排除故障可能会非常困难。
    • 我同意。您可以通过对路线使用常量来稍微减少影响,例如[RoutePrefix(RouteAreas.Accounts)],覆盖 RoutePrefixAttribute 以使用自定义逻辑进行扩展,并且在类似的情况下,我们使用使用反射的(门控签入)单元测试对此类属性使用进行单元测试。例如,您可以验证控制器类型命名空间是否与您的属性匹配(如果您对此感兴趣,我可以给您一个示例代码)。
    • 好主意!我应该想到常量——我曾经为事件代理这样做。您可以将哪种类型的自定义逻辑添加到 RoutePrefixAttribute?是的,如果您愿意分享,我很想看看您的测试实现。
    • @xr280xr 更新了我的答案作为对您问题的回复
    猜你喜欢
    • 2011-03-17
    • 2017-10-09
    • 2016-12-01
    • 2010-12-09
    • 2018-05-31
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多