【问题标题】:Mvcsitemapprovider Multiple paths to the single pagemvcsitemapprovider 单个页面的多条路径
【发布时间】:2013-11-13 12:18:00
【问题描述】:

我想让面包屑导航到同一页面的 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 时,面包屑看起来像 根>完成>动作

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

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 参数,但效果仍然相同。我将不胜感激。

【问题讨论】:

    标签: c# asp.net-mvc sitemap breadcrumbs mvcsitemapprovider


    【解决方案1】:

    使其工作的关键是要知道每组路由值在 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

    请注意,如果您愿意,也可以通过 inheriting 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 将在备用页面(但不是“主”页面)上自动创建。

    有关可下载的示例,请参阅this post。此外,this post 深入探讨了节点匹配功能的工作原理。

    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 路由”,您会发现很多很棒的教程。

    提示: AttributeRouting 通过使用多个 Route 属性装饰一个操作方法,可以轻松地为它提供多个路由。

    [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 和可见性提供程序来调整菜单和面包屑路径的外观。在this post 上可以下载这两种技术的演示。

    【讨论】:

    • 非常感谢您的回答。不幸的是,它没有帮助。我已经更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2017-12-07
    • 2014-03-04
    • 1970-01-01
    • 2021-04-16
    • 2010-09-09
    相关资源
    最近更新 更多