Я реализую сайт, в котором есть поиск, который можно выполнить с помощью методов Controller, доступ к которым осуществляется по двум различным маршрутам. Один из них зависает от маршрута по умолчанию (с использованием либо данных Post, либо значений строки запроса для параметров поиска), а второй - URL-адреса оптимизации SEO, который получает местоположение и фразу через два значения маршрута. Второй маршрут выглядит так:
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 для текущего запроса, я могу сохранить текущее имя контроллера и действия (без необходимости знать, какие они есть) - однако при этом пропускается некоторая важная информация из ModelState - то есть любые дополнительные параметры поиска, которые были предоставлены - т.е. он работает, если текущий Url /Search/London/Widgets
, но если /Search/London/Widgets?PageSize=50
, то параметр PageSize
не сохраняется в исходящей ссылке.
Еще хуже, если это URL, не относящийся к SEO - то есть /Search?Location=London&Phrase=Widgets
, исходящий URL просто становится /Search?Page=x
.
Мои параметры поиска считываются из запроса в тип модели, который затем передается как на страницу хоста, так и на сам пейджер, так что в теории я мог бы просто всегда генерировать их из этого - но я получаю все параметры в URL, даже если они являются значениями по умолчанию (поэтому их не нужно указывать), поэтому URL выглядит ужасно.
Как мне добиться того, чего я хочу !? Я чувствую, что ничего не знаю о MVC внезапно!