我无法解释(或重现)您在斜杠后面看到的行为,但我确实看到了一个潜在问题。
在将节点与传入路由匹配时,以下 2 个节点是不明确的:
<mvcSiteMapNode title="Manage Users" controller="User" action="ManageUsers">
<mvcSiteMapNode title="Users" controller="User" action="ManageUsers" preservedRouteParameters="id">
在这两种情况下,它们都将匹配 URL /User/ManageUsers。这是因为preservedRouteParameters 只在有参数要保留时才起作用,所以它就像一个可选值。
解决此问题的最简单方法是重命名其中一个操作方法。通常,这些是 2 个不同的功能部分(名为 Index 和 Details),通过将它们放入不同的操作方法来应用关注点分离是一件好事。
或者,您可以为第一个节点定义单独的路由,然后显式调用该路由。
routes.MapRoute(
name: "User_MangageUsers",
url: "User/ManageUsers",
defaults: new { controller = "User", action = "ManageUsers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
还有你的节点:
<mvcSiteMapNode title="Manage Users" controller="User" action="ManageUsers" route="User_MangageUsers">
<mvcSiteMapNode title="Users" controller="User" action="ManageUsers" preservedRouteParameters="id">
这确实不能解决page 参数的问题。但是您不应该有一个,因为默认情况下会忽略查询字符串值。我怀疑你的路由配置有问题,但由于你没有发布它,我无法准确告诉你它是什么。
在v4.6.10 中添加了一项功能,允许您将查询字符串参数用作路由匹配的一部分,并且在v4.6.18 中进行了增强以使查询字符串键不区分大小写。
如果您使用的是低于 v4.6.10 的版本,则应升级。如果您至少使用 v4.6.10,则可以通过添加 page 参数作为保留的路由参数来解决此问题。
<mvcSiteMapNode title="Manage Users" controller="User" action="ManageUsers" route="User_MangageUsers" preservedRouteParameters="page">
<mvcSiteMapNode title="Users" controller="User" action="ManageUsers" preservedRouteParameters="id">
根据您的路线更新
我仍然无法重现该问题。
但是,您的路由配置确实存在问题 - 即,在单个路由上指定 2 个可选参数是无效的。这可能与您的尾部斜杠问题有关,因为当您关闭两个可选参数时,生成 URL 时结果将包含一个额外的尾部斜杠。在您当前的路由配置下,Default 路由是无法到达的执行路径。
您可以通过更改路由来解决此问题。
routes.MapRoute(
name: "DefaultwithType",
url: "{controller}/{action}/{id}/{type}",
defaults: new { type = UrlParameter.Optional });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" });
现在:
/User/ManageUsers/1/SomeType - matches DefaultwithType
/User/ManageUsers/1 - matches DefaultwithType
/User/ManageUsers - matches Default
/User - matches Default (with action "Index")
/ - matches Default (with controller "Home", action "Index")
使用此路由配置,您可以通过明确指定路由来消除节点之间的歧义。这可能需要也可能不需要 - 先尝试修复节点,然后再修复。
<mvcSiteMapNode title="Manage Users" controller="User" action="ManageUsers" route="Default">
<mvcSiteMapNode title="Users" controller="User" action="ManageUsers" route="DefaultwithType" preservedRouteParameters="id">
更新以使 Grid 在“用户”节点上工作
// Route to force match with "Users" node
routes.MapRoute(
name: "User",
url: "User/ManageUsers/{id}",
defaults: new { controller = "User", action = "ManageUsers" });
routes.MapRoute(
name: "DefaultwithType",
url: "{controller}/{action}/{id}/{type}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
节点:
<mvcSiteMapNode title="Manage Users" controller="User" action="ManageUsers" route="Default">
<mvcSiteMapNode title="Users" controller="User" action="ManageUsers" route="User" preservedRouteParameters="id,page">
现在User 路由将优先于Default 路由。除非提供 4 段 URL,否则 DefaultwithType 路由将不匹配 - 如果您的应用程序中有 4 个段的 URL,您可能需要一些固定段或约束,您不打算调用最后一个段 {type} .
我还在preservedRouteParameters 中包含了“页面”。这可能不是必需的,但如果包含它,它应该匹配页码是否在请求中。
“MvcSiteMapProvider_AttributesToIgnore”用于在节点上制作不包含在路由匹配中的自定义属性。它与忽略传入 URL 中的值无关。