mvcSitemap和多个路由

时间:2015-02-26 13:18:50

标签: asp.net-mvc asp.net-mvc-routing mvcsitemapprovider

我正在尝试使用MVC站点地​​图为我的应用程序创建面包屑跟踪。我有多个路由进入用户控制器,需要为每个路由器保留面包屑。 mvcSiteMap如何将每个节点映射到路由?

我有以下可能的路线进入用户:

  

/用户/ {动作} / {用户ID}

     

/用户/ {GROUPID} / {行动} / {用户ID}

我想分别使用以下痕迹路径:

  

App Root>用户> {用户名}> {操作}

     

App Root>集团管理> {群组名称}> {用户名}> {操作}

上面第一条路线很直接,我用[SiteMapTitle(“Mail”)]装饰了Details控制器,以显示对象Mail属性而不是“Details”,编辑用[SiteMapTitle(“Mail”)修饰“,Target = AttributeTarget.ParentNode)]以在编辑时保留电子邮件地址。

但是,在使用第二条路线时,我无法弄清楚如何做到这一切。面包屑跟踪根本不显示任何内容。 “组”部分中的“用户”部分似乎不执行任何操作。实现这一目标的最佳方法是什么?

Mvc.Sitemap:

    <mvcSiteMapNode title="User Management" controller="User" action="Index">
      <mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id">
        <mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id"/>
      </mvcSiteMapNode>
    </mvcSiteMapNode>

    <mvcSiteMapNode title="Group Management" controller="Group" action="Index">
      <mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="id">
        <mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="id"/>

        <mvcSiteMapNode title="Users" controller="User" action="Index" preservedRouteParameters="groupid">
          <mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id, groupid">
            <mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id, groupid"/>
            <mvcSiteMapNode title="Manage" action="Manage" controller="User" preservedRouteParameters="id, groupid"/>
          </mvcSiteMapNode>
        </mvcSiteMapNode>


      </mvcSiteMapNode>
      <mvcSiteMapNode title="New" action="Create" controller="Group" />
    </mvcSiteMapNode>
    ...
  </mvcSiteMapNode>

路线:

routes.MapRoute("ByGroup", "User/{groupid}/{action}/{id}",
                        new { controller = "User", action = "Index", id = UrlParameter.Optional }, new { groupid = new GuidConstraint() });

routes.MapRoute("ByGroup2", "User/{groupid}/{action}/{id}",
                        new { controller = "User", action = "Index", id = UrlParameter.Optional, groupid = UrlParameter.Optional }, new { groupid = new GuidConstraint() });


routes.MapRoute("User", "User/{action}/{id}",
                        new { controller = "User", action = "Index", id = UrlParameter.Optional });


routes.MapRoute("Default", "{controller}/{action}/{id}",
                        new { controller = "Home", action = "Index", id = UrlParameter.Optional });

1 个答案:

答案 0 :(得分:2)

节点:

<mvcSiteMapNode title="User Management" controller="User" action="Index" route="Default">
    <mvcSiteMapNode title="Details" action="Details" controller="User" route="Default" preservedRouteParameters="id">
        <mvcSiteMapNode title="Edit" action="Edit" controller="User" route="Default" preservedRouteParameters="id"/>
    </mvcSiteMapNode>
</mvcSiteMapNode>

<mvcSiteMapNode title="Group Management" controller="Group" action="Index">
    <mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="groupid">
        <mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="groupid"/>

        <mvcSiteMapNode title="Users" controller="User" action="Index" route="ByGroup" preservedRouteParameters="groupid">
            <mvcSiteMapNode title="Details" action="Details" controller="User" route="ByGroup" preservedRouteParameters="id, groupid">
                <mvcSiteMapNode title="Edit" action="Edit" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
                <mvcSiteMapNode title="Manage" action="Manage" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
            </mvcSiteMapNode>
        </mvcSiteMapNode>

    </mvcSiteMapNode>
    <mvcSiteMapNode title="New" action="Create" controller="Group" />
</mvcSiteMapNode>

路线:

routes.MapRoute(
    name: "Group", 
    url: "Group/{action}/{groupid}",
    defaults: new { controller = "Group", action = "Index", groupid = UrlParameter.Optional });

routes.MapRoute(
    name: "ByGroup",
    url: "User/{groupid}/{action}/{id}",
    defaults: new { controller = "User", action = "Index", id = UrlParameter.Optional },
    constraints: new { groupid = new GuidConstraint() });

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

说明

您已在ByGroup2路线上定义了2个可选细分受众群,但这是不允许的。可选段必须位于URL的最右侧位置,并且不能跟随必需的段。这可能会导致问题。

此外,我没有看到ByGroup2路线的任何真正目的。

/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Edit/123 - matches ByGroup
/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Index - matches ByGroup
/User/Edit/123 - matches User
/User/Index - matches User

我无法想到与ByGroup2匹配的案例。但是如果它 匹配,那么你的参数将被放入不同的路由密钥中,而不是匹配User路由,这可能会让人感到困惑。

此外,您的User路线似乎无法在Default路线上添加任何内容。因此,您的路线配置可能看起来像这样,并做同样的事情(减去路线值位置的混淆,这可能会导致您的问题)。

routes.MapRoute("ByGroup", "User/{groupid}/{action}/{id}",
                    new { controller = "User", action = "Index", id = UrlParameter.Optional }, new { groupid = new GuidConstraint() });

routes.MapRoute("Default", "{controller}/{action}/{id}",
                    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

然后匹配就像这样。

/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Edit/123 - matches ByGroup
/User/131f89da-0dca-40f0-bc99-41559d13fc7f/Index - matches ByGroup
/User/Edit/123 - matches Default
/User/Index - matches Default

但是,您的preserveRouteParameters也存在问题。

<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="id">
    <mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="id"/>

        <mvcSiteMapNode title="Users" controller="User" action="Index" preservedRouteParameters="groupid">
            <mvcSiteMapNode title="Details" action="Details" controller="User" preservedRouteParameters="id, groupid">
                <mvcSiteMapNode title="Edit" action="Edit" controller="User" preservedRouteParameters="id, groupid"/>
                <mvcSiteMapNode title="Manage" action="Manage" controller="User" preservedRouteParameters="id, groupid"/>
            </mvcSiteMapNode>
        </mvcSiteMapNode>
    </mvcSiteMapNode>
</mvcSiteMapNode>

要使savedRouteParameters匹配多个级别,必须提供祖先节点的所有自定义路由值(在本例中为idgroupid)。此外,它们必须具有相同的含义。为了实现这一点,id必须始终在整个节点中引用同一个实体,并且无论多深都必须包含在每个链接中。您必须为Group实体选择不同的路由密钥,而不是为User实体选择。

要清理它,您可以再次更改路径,将所有信息放入所需的路径中。你已经完成了大部分工作 - 你只需要修复Group节点的id。

routes.MapRoute(
    name: "Group", 
    url: "Group/{action}/{groupid}",
    defaults: new { controller = "Group", action = "Index", groupid = UrlParameter.Optional });

routes.MapRoute(
    name: "ByGroup",
    url: "User/{groupid}/{action}/{id}",
    defaults: new { controller = "User", action = "Index", id = UrlParameter.Optional },
    constraints: new { groupid = new GuidConstraint() });

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

节点:

<mvcSiteMapNode title="Details" action="Details" controller="Group" preservedRouteParameters="groupid">
    <mvcSiteMapNode title="Edit" action="Edit" controller="Group" preservedRouteParameters="groupid"/>

    <mvcSiteMapNode title="Users" controller="User" action="Index"  route="ByGroup" preservedRouteParameters="groupid">
        <mvcSiteMapNode title="Details" action="Details" controller="User" route="ByGroup" preservedRouteParameters="id, groupid">
        <mvcSiteMapNode title="Edit" action="Edit" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
    <mvcSiteMapNode title="Manage" action="Manage" controller="User" route="ByGroup" preservedRouteParameters="id, groupid"/>
</mvcSiteMapNode>

请注意,/Group/Index节点下方的每条路线现在都有groupid,而groupid键始终指的是同一个实体?

另外,为了确保我们只匹配相关路线,我们明确指定它。如果我们没有,那么用户节点将是不明确的,因此您将得到错误的痕迹路径(匹配胜利的第一个节点)。

route="ByGroup"

使用上述配置,您需要构建指向包含当前Users的{​​{1}},Users/DetailsUsers/EditUsers/Manage的链接(当然还有当前的用户ID)。

groupid

然后当您导航到&#34;编辑用户&#34;链接,groupid将在当前请求中,在解析URL时将其提供给@Html.ActionLink("Edit User", "Edit", "User", new { id = <userid>, groupid = <groupid> }, null) 节点,Users/Details节点和Group/Edit节点,以便您可以导航回这些位置通过面包屑踪迹。

有关其他示例,请参阅代码下载of this article中的Forcing-A-Match-2-Levels示例。

没有组的用户部分将与Group/Details路由匹配,并在构建不带Default的网址时显示相应的痕迹痕迹。

所以我们明确指定了默认路由:

groupid

并构建如下的网址:

route="Default"