使其工作的关键是要知道每组路由值在 SiteMap 中必须是唯一的。也就是说,您需要向除 1 个以外的所有路由添加另一个参数,并且每个节点上的参数名称或其值必须不同。
<mvcSiteMapNode title="New" controller="Actions" action="NewActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Continues" controller="Actions" action="ContinuesActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" someParameter="1"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Finished" controller="Actions" action="FinishedActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" someParameter="2"/>
</mvcSiteMapNode>
路由值的组合(或在 url 属性上设置的显式 URL)是如何将节点标识为当前节点并且第一个匹配项总是获胜的方式。但是如果你添加额外的数据,那么每个节点将是完全唯一的。
如果您使用的是默认路由,那么您的 URL 将如下所示:
- /促销/行动/行动
- /Promotion/Actions/Action?someParameter=1
- /Promotion/Actions/Action?someParameter=2
请注意,如果您愿意,也可以通过继承 RouteBase或向路由添加自定义参数来自定义 MVC 路由,以使 URL 更加用户友好。
一旦您按照自己喜欢的方式设置了 URL(即 UNIQUE URL),您就可以使用规范标签 HTML 帮助程序来确保只有“主” URL 被搜索引擎索引,而其他 URL 被忽略。您只需要将 canonicalKey 或 canonicalUrl 属性设置为“主”节点的属性。
<mvcSiteMapNode title="New" controller="Actions" action="NewActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" key="TheMainAction"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Continues" controller="Actions" action="ContinuesActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" someParameter="1" canonicalKey="TheMainAction"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Finished" controller="Actions" action="FinishedActions" area="Promotion">
<mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" someParameter="2" canonicalKey="TheMainAction"/>
</mvcSiteMapNode>
然后,您只需将@Html.MvcSiteMap().CanonicalTag()
HTML 帮助程序添加到布局页面的 HEAD 部分,规范 URL 将在备用页面(但不是“主”页面)上自动创建。
请参阅这篇文章以获取可下载的示例。此外,这篇文章深入探讨了节点匹配功能的工作原理。
MVC 路由
请记住,路由决定了 URL 的构建方式。查看您的 RouteConfig.cs 文件。
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
如您所见,默认路由仅使用“id”作为参数。您添加的任何不是控制器、操作或 id 的内容都将成为查询字符串的一部分。您可以根据应用程序的需要添加其他路由、参数和约束(更具体的路由属于默认路由之前,通常您应该单独保留默认路由)。查看MSDN以深入了解路由或谷歌“mvc 路由”,您会发现很多很棒的教程。
提示: AttributeRoutingRoute
通过使用多个属性来装饰动作方法,可以轻松地为动作方法提供多个路由。
[Route("new-actions/action-tab-details/{actionTabGuid}")]
[Route("continues-actions/action-tab-details/{actionTabGuid}")]
[Route("finished-actions/action-tab-details/{actionTabGuid}")]
public ActionResult ActionTabDetails(Guid actionTabGuid)
{
ActionTab model = actionTabRepo.Get(actionTabGuid, "ActionGroup");
if (model.Status == ActionStatus.New)
{
//Parameter with I want to pass to the DynamicNodeProvider or select current node
}
//another conditions
return View("ActionTab/ActionTabDetails", model);
}
如果您不想弄乱路由,我建议您只使用默认路由并使用“id”作为您的 Guid 值(因为大多数操作无论如何都只有一个)。如果“actionStatus”对您的应用程序没有任何意义,并且您的路由没有将其指定为必需值(默认路由没有),则您不需要将“actionStatus”添加到您的操作方法中。
MvcSiteMapProvider 路由
另一方面是与 MvcSiteMapProvider 匹配的节点。使用自定义路由值(参数)时,您需要配置 MvcSiteMapProvider 以便它了解您正在使用自定义参数。您可以通过将它们的每个可能组合添加为单独的节点(使用IDynamicNodeProvider或 ISiteMapNodeProvider),否则您将需要强制每个值与带有preservedRouteParameters 的单个节点相匹配。如果所有页面都在搜索引擎中编入索引很重要,请为每个值使用单独的节点。如果您的页面主要用于数据输入,请使用 reservedRouteParameters。通常,在使用 reservedRouteParameters 时,您还必须使用 SiteMapTitleAttribute 和可见性提供程序来调整菜单和面包屑路径的外观。在这篇文章中有这两种技术的演示可供下载。