我正在尝试使用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 });
答案 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匹配多个级别,必须提供祖先节点的所有自定义路由值(在本例中为id
和groupid
)。此外,它们必须具有相同的含义。为了实现这一点,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/Details
,Users/Edit
和Users/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"