【问题标题】:Using RouteLink with Areas将 RouteLink 与区域一起使用
【发布时间】:2012-06-29 14:50:29
【问题描述】:

在我的 MVC 应用程序中,我定义了一个默认路由:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new []{ "Demo.Controllers" }
);

我创建了一个名为 Admin 的新区域,并在 AdminAreaRegistration 类中添加了一条路由:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "Admin_default",
        "Admin/{controller}/{action}/{id}",
        new { action = "Index", controller = "Home", id = UrlParameter.Optional }
    );
} 

在我的主 _Layout 文件中,我尝试执行以下操作:

@Html.RouteLink("Admin", "Admin_default")

它仅在某些情况下有效(例如,如果我已经在管理页面中)。如果我在网站的 /Home/About 部分,则会生成如下所示的 URL:

/Admin/Home/About

如果我在 Home 控制器的 Index 操作中(在主区域,而不是管理员),那么 URL 会像这样生成:

/Admin

为什么 RouteLink 不像我认为应该使用 MVC 中的区域那样工作?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-routing asp.net-mvc-areas


    【解决方案1】:

    @Html.RouteLink("Admin", "Admin_default") 此路由使用名称为Admin_default 的路由,因此它将始终使用该路由来生成 url。

    @Html.RouteLink("Admin", "Admin_default", new { controller = "Home", action = "Index" })

    当您不指定诸如路由值之类的东西时,大多数 MVC 使用当前存在的值。在这种情况下,由于 actioncontroller 的值为 null,它会查看 RouteValues 并检查它们是否存在,如果找到它们,则使用在那里找到的值。

    这有时很有帮助。例如,如果您希望 {id} 填充页面上使用的相同值。

    网址:/home/edit/1701

    @Html.RouteLink("Refresh", "Default") 将产生完全相同的 url - 如果需要,您可以指定覆盖。

    【讨论】:

    • 我希望 URL 是 /Admin。我对 Admin_default 路由的默认设置是:controller = "Home",action = "Index"。为什么它会使用 About 作为我的操作?
    • 啊,在这种情况下,它正在使用请求中的现有路由值 - 更新答案
    • 那么为什么它使用页面中的当前路由值呢?这对我来说似乎很奇怪。
    【解决方案2】:

    我还建议不要命名您的路线。您可以通过在创建路由名称时将 null 传递给路由名称 arg 来强制自己执行此操作。

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(null,
            "Admin/{controller}/{action}/{id}",
            new { action = "Index", controller = "Home", id = UrlParameter.Optional }
        );
    }
    

    然后您可以像这样使用 RouteLink:

    @Html.RouteLink("Admin", 
        new { controller = "Home", action = "Index", area = "Admin" })
    

    回复评论

    希望我可以说我想出了这个主意。从 Steve Sanderson 的 MVC 书中学到了这一点。有大量将路由名称作为参数的方法重载(RouteLink,还有 RedirectToRoute 等)。不使用路由名称会迫使您使用这些方法的其他重载,IMO 更直观且更容易“正确”。

    【讨论】:

    • 我不知道你能做到这一点......我想,因为路线名称必须是唯一的,所以它们是必需的。头脑=吹了
    【解决方案3】:

    不建议为您的路线命名,因为它会在您的视图中创建对现有路线的依赖关系。我建议使用空值

    【讨论】:

    • 依赖路由名称来生成传出 URL 的问题在于,这样做打破了 MVC 设计模式的核心关注点分离。在视图或操作方法中生成链接或 URL 时,我们希望关注用户将被定向到的操作和控制器,而不是将使用的 URL 的格式。通过将不同路由的知识引入视图或控制器,我们正在创建我们希望避免的依赖关系。 (指定 null 作为名称并在代码中使用 cmets)(Apress Pro ASP.NET MVC3)
    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2012-05-31
    相关资源
    最近更新 更多