似乎无法使MvcSiteMapProvider与具有路由值的路由一起使用

时间:2014-02-13 18:14:17

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

我目前正在使用MvcSiteMapProvider为我动态生成面包屑

@Html.MvcSiteMap().SiteMapPath()

我的网站全部都是品牌,而网址中的第一个值包含该品牌,所以我的路线都是这样的:

routes.MapRoute("Terms", "{brand}/Terms", new { controller = "Legal", Action = "Terms" });
routes.MapRoute("Privacy", "{brand}/Privacy", new { controller = "Legal", Action = "Privacy" });
routes.MapRoute("Home", "{brand}", new { controller = "Home", action = "Dashboard" });
routes.MapRoute("Dashboard", "{brand}/Dashboard", new { controller = "Home", action = "Dashboard" });

这在以前的版本中有所改变,但我看到了使用两个不同品牌查看相同路线的间歇性问题。一旦我更新,我现在什么都没有。

我的站点地图如下所示:

  <mvcSiteMapNode title="Home" url="/{brand}" route="Home">
    <mvcSiteMapNode title="Dashboard" url="/{brand}/Dashboard" route="Dashboard" />
    <mvcSiteMapNode title="Terms" url="/{brand}/Terms" route="Terms" />
    <mvcSiteMapNode title="Privacy" url="/{brand}/Privacy" route="Privacy" />
  </mvcSiteMapNode>

我已经通过文档挖掘更新,并尝试了大量不同的东西。我已将源代码包含在我的项目中并进行了调试,我唯一看到的是无论我做什么,currentNode始终为null。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

url属性/属性用于配置具有绝对路径的URL,而不是用于配置路由。当您使用url属性时,它基本上禁用节点上的路由支持并将其转换为基于URL的节点。这与ASP.NET的互操作性或在SiteMap中提供外部链接非常方便。您的网址不匹配,因为它们不是真正的网址,这是预期的。

要在节点上使用MVC路由,您基本上必须按照配置ActionLink或RouteLink的方式配置它们(与可选路由属性一起使用时)。

<mvcSiteMapNode title="Home" controller="Home" action="Dashboard" route="Home">
    <mvcSiteMapNode title="Dashboard" action="Dashboard" route="Dashboard" />
    <mvcSiteMapNode title="Terms" controller="Legal" action="Terms" route="Terms" />
    <mvcSiteMapNode title="Privacy" controller="Legal" action="Privacy" route="Privacy" />
</mvcSiteMapNode>

另请注意,使用XML进行配置时,区域和控制器属性会自动从最后定义它们的祖先节点继承,这可以为您节省一些繁重的工作。而且,这些路线完全是可选的。

<mvcSiteMapNode title="Home" controller="Home" action="Dashboard">
    <mvcSiteMapNode title="Dashboard" action="Dashboard" />
    <mvcSiteMapNode title="Terms" controller="Legal" action="Terms" />
    <mvcSiteMapNode title="Privacy" controller="Legal" action="Privacy" />
</mvcSiteMapNode>

但是使用自定义路由参数会变得棘手。请查看this answer,了解如何做到这一点。

<强>更新

我再看看你的配置,我想我已经发现了这个问题。您没有将节点配置为考虑品牌参数,因此它们永远不会匹配。如果(我怀疑)你试图让所有品牌都匹配这一组节点,你需要添加“品牌”作为保留的路由参数,强制它匹配。

<mvcSiteMapNode title="Home" controller="Home" action="Dashboard" preservedRouteParameters="brand">
    <mvcSiteMapNode title="Dashboard" action="Dashboard" preservedRouteParameters="brand"/>
    <mvcSiteMapNode title="Terms" controller="Legal" action="Terms" preservedRouteParameters="brand"/>
    <mvcSiteMapNode title="Privacy" controller="Legal" action="Privacy" preservedRouteParameters="brand"/>
</mvcSiteMapNode>

这会导致当前请求的品牌在比较之前被复制到节点的RouteValues中。要获得匹配,您需要在节点的RouteValues中具有与当前请求的RouteValues中相同的键和值(值不区分大小写)。如果不这样做,currentNode将始终为null。

之前似乎有用的原因是因为v4.4.x也在URL上匹配,这是导致无效匹配发生的错误。

有一篇完整的帖子详细介绍了匹配工作的标题How to Make MvcSiteMapProvider Remember a User's Position

更新2

我还注意到您的路线上没有设置默认设置。 “行动”应该是“行动”,因为路线键区分大小写。

// This is what you have
routes.MapRoute("Terms", "{brand}/Terms", new { controller = "Legal", Action = "Terms" });
routes.MapRoute("Privacy", "{brand}/Privacy", new { controller = "Legal", Action = "Privacy" });

// Action should always be lowercase (action)
routes.MapRoute("Terms", "{brand}/Terms", new { controller = "Legal", action = "Terms" });
routes.MapRoute("Privacy", "{brand}/Privacy", new { controller = "Legal", action = "Privacy" });