1

我想让面包屑导航到同一页面的 3 条路径。网站地图在底部。

<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" actionStatus="1"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Finished" controller="Actions" action="FinishedActions" area="Promotion">
  <mvcSiteMapNode title="Action" controller="Actions" action="ActionTabDetails" area="Promotion" actionStatus="2"/>
</mvcSiteMapNode>

我尝试使用属性“类型”和“键”,但没有帮助。每次我打开动作 ActionDetails 时,面包屑看起来像 root > Finished > Action

路径的选择在控制器中由模型的状态决定。我现在应该编写自己的 DynamicNodeProvider 但我不知道如何将参数从控制器传递给提供程序。我不能使用动作注释,因为我现在在动作主体中的模型条件如下:

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

我试过了:

SiteMap.CurrentNode = SiteMap.Provider.FindSiteMapNodeFromKey("new");

但在控制器中只是吸气剂。

我将非常感谢您的帮助。

更新:

我使用可选参数进行了操作:

public ActionResult ActionTabDetails(Guid actionTabGuid, int actionStatus=0)

但每个网址都喜欢

  • /Promotion/Actions/Action?actionTabGuid=822ed729-8edd-4301-970a-867d2b4f9246
  • /Promotion/Actions/Action?actionTabGuid=822ed729-8edd-4301-970a-867d2b4f9246&actionStatus=1
  • /Promotion/Actions/Action?actionTabGuid=822ed729-8edd-4301-970a-867d2b4f9246&actionStatus=2

不带参数直接到第一个节点。我已经尝试过使用 obvers 参数,但效果仍然相同。我将不胜感激。

4

1 回答 1

0

使其工作的关键是要知道每组路由值在 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 和可见性提供程序来调整菜单和面包屑路径的外观。在这篇文章中有这两种技术的演示可供下载。

于 2013-11-14T01:47:00.430 回答