【发布时间】:2010-03-11 14:23:23
【问题描述】:
我正在实现一个站点,该站点具有可以通过从两个不同路径访问的控制器方法执行的搜索。一个挂起默认路由(使用 Post 数据或查询字符串值作为搜索参数),一个是 SEO 优化 url,它通过两个路由值获取位置和短语。第二条路线如下所示:
routes.MapRoute("SEOSearch", "Search/{seoLocation}/{seoSearchString}",
new { controller = "Search",
action = "SEOResults",
seoLocation = (string)null,
seoSearchString = (string)null });
您可能想知道为什么我有两条不同的路线 - 这是因为搜索提供了许多其他参数,而不仅仅是位置和短语 - 但我希望 SEO 的 url 将这两个包含在路径中,而不是使用查询字符串.
正如我所说,第一个路由是默认的 /controller/action/id 路由,正确的控制器/操作是“搜索”和“索引”。
最后,两个动作在控制器中执行相同的搜索操作,并且都将使用索引视图呈现它们的结果,因为它们的结果模型是相同的。
在索引视图中,我对搜索词使用一个局部视图,另一个用于结果,另一个用于分页。
我遇到的问题是让分页控件呈现正确的链接以启动对下一页的当前搜索使用与当前请求相同的 URL 格式。
我想要什么
因此,假设您已导航到 /Search?Location=[location]&Phrase=[phrase],我希望寻呼机生成的第 2 页链接为 /Search?Location=[location]&Phrase=[phrase]&Page=2。
但是,如果您使用 /Search/[location]/[phrase] 启动搜索,我希望第 2 页的链接为 /Search/[location]/[phrase]?Page=2。
我有什么
我得到的最接近的是:
<%= Html.RouteLink("Previous Page",
RouteHelpers.Combine(ViewContext.RouteData.Values,
new RouteValueDictionary() { { "Page", Model.Results.PageNo + 1}})) %>
RouteHelpers.Combine 是我编写的一个扩展,它接受两个对象并将它们合并到一个 RouteValueDictionary 中。通过获取当前请求的 RouteValues,我可以保留当前的 Controller 和 Action 名称(无需知道它们是什么)——但这会遗漏 ModelState 中的一些重要信息——即提供的任何额外搜索参数——即如果当前的 Url 是 /Search/London/Widgets,它可以工作,但如果它是 /Search/London/Widgets?PageSize=50,那么 PageSize 参数不会被持久化到传出链接中。
更糟糕的是,如果它是一个非 SEO 的 url - 即/Search?Location=London&Phrase=Widgets,那么传出的 url 就会变成 /Search?Page=x。
我的搜索参数从请求中读取为模型类型,然后将其馈送到主机页面和寻呼机本身,因此理论上我总是可以简单地从中生成它们 - 但我最终得到了所有url 中的参数,即使它们是默认值(因此不需要提供它们) - 所以 url 看起来很丑。
如何实现我想要的!?我突然觉得我对 MVC 一无所知!
【问题讨论】:
标签: c# asp.net-mvc asp.net-mvc-routing