节点:
<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
但是,您的 reservedRouteParameters 也存在问题。
<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>
为了使preservedRouteParameters 匹配多个级别,必须提供祖先 节点的所有自定义路由值(在本例中为id 和groupid)。此外,它们必须具有相同的含义。为此,id 必须始终通过节点一直引用同一个实体,并且无论多深都必须包含在每个链接中。您必须为组实体选择一个不同的路由键而不是用户实体。
要清理这一点,您可以再次更改路线,将所有信息放入所需的路线中。您已经完成了大部分工作 - 您只需要修复 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、Users/Details、Users/Edit 和Users/Manage 的链接,其中包括当前groupid(当然还有当前用户ID) .
@Html.ActionLink("Edit User", "Edit", "User", new { id = <userid>, groupid = <groupid> }, null)
然后,当您导航到“编辑用户”链接时,groupid 将出现在当前请求中,在解析 URL 时会将其提供给 Users/Details 节点、Group/Edit 节点和 Group/Details 节点,因此您可以通过面包屑路径导航回这些位置。
有关另一个示例,请参阅代码下载 of this article 中的 Forcing-A-Match-2-Levels 示例。
没有组的用户部分将匹配Default 路由,并在构建没有groupid 的URL 时显示适当的面包屑路径。
所以我们明确指定默认路由:
route="Default"
并构建如下 URL:
@Html.ActionLink("Edit User", "Edit", "User", new { id = <userid> }, null)