MVC RouteConfig 影响了 Html.ActionLink() 辅助方法
MVC RouteConfig affected the Html.ActionLink() helper method
在我的 MVC 项目中,我有 Item 控制器和一些操作,例如 Index。
RouteConfig 包括:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
在某些视图中,我使用了辅助方法 Html.ActionLink("Items","Index","Item")为索引操作创建锚点。所以锚结果的 href 将是 (/Item/Index)
现在,我需要映射以下 static URL:
/IndirectItem/Index
使用默认参数(indirect = true Item 控制器的 Index 操作),因此 RouteConfig 将是:
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index", indirect = true }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
看起来不错,客户端请求映射正确,但所有锚点都来自 Html.ActionLink("Items","Index","Item" ) 辅助方法被映射到 URL (/IndirectItem/Index) 而不是 (/Item/Index).
如何在不将所有 Html.ActionLink() 更改为 Html.RouteLink() 或为原来的 url 添加另一条路线 ?
您遇到此问题是因为 Html.ActionLink
使用路由 table 生成 URL,并且由于 IndirectItem
路由与 Html.ActionLink("Items","Index","Item")
匹配(因为它具有索引操作和项目在路由和操作中指定的控制器 link)。由第一场比赛完成解析,因此路线注册顺序很重要
通过添加DefaultItem
路线:
routes.MapRoute(
name: "DefaultItem",
url: "Item/Index/{id}",
defaults: new { controller = "Item", action = "Index", id = UrlParameter.Optional }
);
在您当前路线之前:
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index/,
defaults: new { controller = "Item", action = "Index", indirect = true}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
应该解决问题
另一个选项可能是创建继承自 Item 控制器的空 IndirectItem 控制器:
public IndirectItemController : ItemController
{
}
然后将路线更改为
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index/,
defaults: new { controller = "IndirectItem", action = "Index", indirect = true}
);
使用约束 将是您问题的便捷解决方案。
使用以下 IndirectItem 路线代替您的路线。
routes.MapRoute(
name: "IndirectItem",
url: "{staticVar}/{action}",
defaults: new { controller = "Item", action = "Index", indirect = true},
constraints: new { staticVar = "IndirectItem" }
);
并且您不需要对 默认 路由进行任何更改。
我用得很好。
Omar Gohar 和 Alex Art 给出的答案具有误导性。
您 运行 遇到的问题是 生成 URL 时您的路线不匹配。这仅仅是因为您没有提供所有路由值来在 ActionLink
.
中创建匹配项
@Html.ActionLink("Items", "Index", "Item", new { indirect = true }, null)
如果无法更改 ActionLink
声明,您可以使用 DataTokens parameter.
将 "indirect"
元数据附加到路由
You use the DataTokens property to retrieve or assign values associated with the route that are not used to determine whether a route matches a URL pattern. These values are passed to the route handler, where they can be used for processing the request.
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index" }
).DataTokens = new RouteValueDictionary(new { indirect = true });
底线是 RouteValues
(如果 URL 模式未提供,则由默认值填充)不用于元数据。它们应该是要匹配的真实数据,以使 URL 独一无二。
当然,如果您实际上没有使用 indirect
路由值,您可以简单地从路由中省略它。
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index" }
);
在我的 MVC 项目中,我有 Item 控制器和一些操作,例如 Index。
RouteConfig 包括:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
在某些视图中,我使用了辅助方法 Html.ActionLink("Items","Index","Item")为索引操作创建锚点。所以锚结果的 href 将是 (/Item/Index)
现在,我需要映射以下 static URL:
/IndirectItem/Index
使用默认参数(indirect = true Item 控制器的 Index 操作),因此 RouteConfig 将是:
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index", indirect = true }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
看起来不错,客户端请求映射正确,但所有锚点都来自 Html.ActionLink("Items","Index","Item" ) 辅助方法被映射到 URL (/IndirectItem/Index) 而不是 (/Item/Index).
如何在不将所有 Html.ActionLink() 更改为 Html.RouteLink() 或为原来的 url 添加另一条路线 ?
您遇到此问题是因为 Html.ActionLink
使用路由 table 生成 URL,并且由于 IndirectItem
路由与 Html.ActionLink("Items","Index","Item")
匹配(因为它具有索引操作和项目在路由和操作中指定的控制器 link)。由第一场比赛完成解析,因此路线注册顺序很重要
通过添加DefaultItem
路线:
routes.MapRoute(
name: "DefaultItem",
url: "Item/Index/{id}",
defaults: new { controller = "Item", action = "Index", id = UrlParameter.Optional }
);
在您当前路线之前:
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index/,
defaults: new { controller = "Item", action = "Index", indirect = true}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
应该解决问题
另一个选项可能是创建继承自 Item 控制器的空 IndirectItem 控制器:
public IndirectItemController : ItemController
{
}
然后将路线更改为
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index/,
defaults: new { controller = "IndirectItem", action = "Index", indirect = true}
);
使用约束 将是您问题的便捷解决方案。
使用以下 IndirectItem 路线代替您的路线。
routes.MapRoute(
name: "IndirectItem",
url: "{staticVar}/{action}",
defaults: new { controller = "Item", action = "Index", indirect = true},
constraints: new { staticVar = "IndirectItem" }
);
并且您不需要对 默认 路由进行任何更改。
我用得很好。
Omar Gohar 和 Alex Art 给出的答案具有误导性。
您 运行 遇到的问题是 生成 URL 时您的路线不匹配。这仅仅是因为您没有提供所有路由值来在 ActionLink
.
@Html.ActionLink("Items", "Index", "Item", new { indirect = true }, null)
如果无法更改 ActionLink
声明,您可以使用 DataTokens parameter.
"indirect"
元数据附加到路由
You use the DataTokens property to retrieve or assign values associated with the route that are not used to determine whether a route matches a URL pattern. These values are passed to the route handler, where they can be used for processing the request.
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index" }
).DataTokens = new RouteValueDictionary(new { indirect = true });
底线是 RouteValues
(如果 URL 模式未提供,则由默认值填充)不用于元数据。它们应该是要匹配的真实数据,以使 URL 独一无二。
当然,如果您实际上没有使用 indirect
路由值,您可以简单地从路由中省略它。
routes.MapRoute(
name: "IndirectItem",
url: "IndirectItem/Index",
defaults: new { controller = "Item", action = "Index" }
);