Mvcsitemapprovider到单个页面的多个路径

时间:2013-11-13 12:18:00

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

我想让breadcrump导航到同一页面的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时,breadcrump看起来像 root&gt;完成&gt;行动

路径的选择在控制器中由模型的状态确定。我现在应该编写自己的DynamicNodeProvider,但我不知道如何从controler将参数传递给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)

但是每个网址都是

  • /促销/操作/动作?actionTabGuid = 822ed729-8edd-4301-970a-867d2b4f9246
  • /促销/操作/动作actionTabGuid = 822ed729-8edd-4301-970a-867d2b4f9246&安培; actionStatus = 1
  • /促销/操作/动作actionTabGuid = 822ed729-8edd-4301-970a-867d2b4f9246&安培; actionStatus = 2

指向没有参数的第一个节点。我已尝试使用obvers参数进行操作,但效果仍然相同。我将感激不尽的帮助。

1 个答案:

答案 0 :(得分: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)的组合是节点被识别为当前节点并且第一个匹配总是获胜的方式。但是如果你添加额外的数据,那么每个节点都将是完全唯一的。

如果您使用的是默认路由,那么您的网址将如下所示:

  • /促销/操作/动作
  • / Promotion / Actions / Action?someParameter = 1
  • /促销/操作/动作?someParameter = 2

请注意,如果您喜欢inheriting RouteBase或者将自定义参数添加到路线中,您也可以自定义MVC路线,以使URL更加用户友好。

一旦您按照自己喜欢的方式设置了URL(即UNIQUE URL),您就可以使用规范标记HTML帮助程序来确保搜索引擎仅对“主”URL编制索引,而忽略其他URL 。您只需要将canonicalKey或canonicalUrl属性设置为“main”节点的属性。

<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”。

MvcSiteMapProvider路由

另一方面是MvcSiteMapProvider的节点匹配。使用自定义路由值(参数)时,需要配置MvcSiteMapProvider,以便它了解您正在使用自定义参数。您可以通过将它们的每个可能组合添加为单独的节点(使用IDynamicNodeProvider或ISiteMapNodeProvider)来执行此操作,或者您需要强制每个值与具有savedRouteParameters的单个节点匹配。如果所有页面都在搜索引擎中编制索引很重要,请为每个值使用单个节点。如果您的页面主要用于数据输入,请使用savedRouteParameters。通常,在使用savedRouteParameters时,您还必须使用SiteMapTitleAttribute和可见性提供程序来调整菜单和痕迹路径的外观。在this post上可以下载这两种技术的演示。