我正在处理的网站有一些相当复杂的路由结构,我们遇到一些使用路由引擎构建URL的困难,就像我们需要构建它们一样。
我们有一个搜索结果页面,它使用基于RegEx的模式匹配将多个变量分组到一个路径段中(即“www.host.com/{structuralParameters}”可以是:“www.host.com/variableA -variableB-variableC“ - 其中变量A到C都是可选的)。经过一番工作,这对我们很有用。
我们遇到的问题解决了ActionLink方法令人讨厌的特性:如果指向相同的控制器/操作,它将保留现有的路由值,无论您是否需要它们。我们更愿意控制链接的外观,在某些情况下,不能保留现有参数。一个例子是我们网站的主导航导向没有设置参数的搜索结果页面 - 如果您愿意,可以使用默认搜索页面。我说这是一个烦人的功能,因为它是一个罕见的ASP.Net MVC框架实例,似乎在没有明显扩展点的情况下决定实现 - 我们宁愿不创建自定义ActionLink代码来在我们的母版页中编写简单的导航链接! / p>
我看到有人说你需要明确地将这些参数设置为空字符串,但是当我们尝试这个时它只是将参数从路由值更改为查询字符串参数。对我来说似乎不应该要求我们明确地将我们未明确传递的值作为参数传递给ActionLink方法,但如果这是我们唯一的选项,我们将使用它。但是目前如果它在查询字符串中显示,那么将参数直接放入路径对我们来说是无用的。
我知道我们的路由结构激怒了这个问题 - 如果我们使用更简单的方法(即www.host.com/variableA/variableB/variableC),我们可能不会有任何问题但我们的URL结构不可协商 - 它旨在满足与可用性,搜索引擎优化和链接/内容共享相关的非常具体的需求。
我们如何使用Html.ActionLink生成指向页面的链接,而不会回退到当前路径数据(或者,如果可能,需要明确排除路径段),即使这些链接导致相同的操作方法?
如果我们确实需要明确排除路径段,我们如何阻止该方法将路由呈现为查询字符串参数?
这个看似很小的问题给我们带来了惊人的悲痛,我将感谢任何帮助解决它。
编辑:根据LukLed的要求,这是一个示例ActionLink调用:
// I've made it generic, but this should call the Search action of the
// ItemController, the text and title attribute should say "Link Text" but there
// should be no parameters - or maybe just the defaults, depending on the route.
//
// Assume that this can be called from *any* page but should not be influenced by
// the current route - some routes will be called from other sections with the same
// structure/parameters.
Html.ActionLink(
"Link Text",
"Search",
"Item",
new { },
new { title = "Link Text" }
);
答案 0 :(得分:20)
在调用Html.ActionLink
或Html.RouteLink
(或任何URL生成方法)时将路由值设置为null或空字符串将清除“环境”路由值。
例如,使用标准MVC控制器/ action / id路由假设您处于“Home / Index / 123”。如果您致电Html.RouteLink(new { id = 456 })
,则MVC会注意到controller="Home"
和action="Index"
的“环境”路线值。它还会注意到id="123"
的环境路由值,但会被显式“456”覆盖。这将导致生成的URL为“Home / Index / 456”。
参数的排序也很重要。例如,假设你打电话给Html.RouteLink(new { action = "About" })
。 “关于”操作将覆盖当前的“索引”操作,“id”参数将完全清除!但是,为什么,你问?因为一旦您使参数段无效,那么它之后的所有参数段都将失效。在这种情况下,“action”被新的显式值无效,因此“id”(在它之后,并且没有显式值)也会失效。因此,生成的URL将只是“Home / About”(没有ID)。
在同一场景中,如果您调用Html.RouteLink(new { action = "" })
,则生成的URL将只是“Home”,因为您使用空字符串使“action”无效,然后导致“id”无效因为它是在无效的“行动”之后发生的。
答案 1 :(得分:4)
似乎最佳解决方案(没有像解决方法一样的味道)是解决问题的方法,它解决了它的根源和路由问题。
我编写了一个名为Route
的自定义RouteWithExclusions
类,它可以定义在生成URL时应排除/删除的路由值名称。问题是当路由通过路由表落下并且后续路由没有相同的路由值名称时...
整个问题在my blog post中详细说明并解释,所有代码也在那里提供。检查一下,它可以帮助您解决此路由问题。我还编写了另外两个MapRoute
扩展方法,这些方法需要额外的参数。
答案 2 :(得分:1)
如果您想完全控制链接,只需自己构建链接:
<a href="~/variableA/variableB/<%= Html.Encode(Model.Target) %>">Click Here</a>
在href
属性中替换您需要的任何内容。