asp.net-mvc - 似乎无法让 MvcSiteMapProvider 处理具有路由值的路由

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

我目前正在使用 MvcSiteMapProvider 通过以下方式动态生成我的面包屑

@Html.MvcSiteMap().SiteMapPath()

我的网站都是品牌的,并且 Url 中的第一个值包含品牌,因此我的路线都如下所示:

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。

有什么想法吗?

最佳答案

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 进行配置时,区域和 Controller 属性会自动从最后定义它们的祖先节点继承,这可以为您节省一些繁重的工作。再说一次,路线是完全可选的。

<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了解如何做到这一点。

更新

我再次查看了您的配置,我想我已经发现了问题。您没有将节点配置为考虑品牌参数,因此它们永远不会匹配。如果(正如我怀疑的那样)您试图使所有品牌都匹配这组节点,则需要添加“brand”作为servedRouteParameter强制其匹配。

<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

我还注意到您的默认值没有在您的路线上正确设置。 “Action”应该是“action”,因为路由键区分大小写。

// 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" });

关于asp.net-mvc - 似乎无法让 MvcSiteMapProvider 处理具有路由值的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21762277/

相关文章:

asp.net - 如何在不使用角色的情况下使用 ASP.NET Web API 实现基于声明的授权?

asp.net-mvc - 尝试添加强类型 View 在 MVC 项目中找不到任何类

c# - 在ASP.NET MVC中解析JSON文件并在网页中显示数据

ruby-on-rails - 通过路由将参数传递给 Controller ​​ Action

javascript - 如何在node/mean/express应用程序中拆分index.js文件?

javascript - 使用 $stateProvider 的 AngularJS/Ionic 路由 - Controller 不会在第二次调用状态时重新加载

.net - 在 IIS 6 上使用 ASP.NET MVC 站点的客户端证书

ios - 为什么我无法获得 MKDirectionResponse

asp.net-mvc-3 - 添加asp.net mvc 3的路由

c# - AsP.NET 4.0 url 路由