Actionresult не вызывается routelink. Форма взыскания виновника?

Я довольно новичок в MVC. Я пытаюсь настроить страницу поиска, которая выполняет поиск в базе данных и возвращает результаты. Поле поиска находится в Html.BeginForm в моем представлении и выглядит следующим образом:

   <% using (Html.BeginForm())
     { %>
      <%= Html.TextBox("searchBox", null, new { @id = "searchBox" })%>
       <div id="searchButtonsDiv">
        <input type="submit" value="Search" />
      </div>
  <% } %>

  //Results are returned in a ul and orgainized


   //Pagination below
   <% if (Model.HasPreviousPage)
      { %>
        <%= Html.RouteLink("Previous", "SearchResults", new { page = (Model.PageIndex - 1) })%>
   <% } %>
   <% if (Model.HasNextPage)
      {  %>
         <%= Html.RouteLink("Next", "SearchResults", new { formCollection = "", page = (Model.PageIndex + 1) })%>
   <% } %>

Я использую FormCollection для передачи моему контроллеру, который выглядит так:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection formCollection, int? page)
    {
        var searchString = formCollection["searchBox"]; 
        var results = resultsRepository.GetResults();

        var paginatedResults = new PaginatedList<Driver>(results, page ?? 0, pageSize);

        return View(paginatedResults);
    }

Все идет нормально. Когда я набираю слово и нажимаю кнопку отправки, вызывается индекс, и база данных возвращается соответственно. ul заполняется результатами, и когда результатов больше, чем pageSize (10 в моем случае), появляется ссылка «Далее».

Когда я нажимаю «Далее», просто загружается страница по умолчанию. Без пагинации и прочего. Я почти уверен, что это связано с тем, что мой Index ActionResult имеет FormCollection в качестве параметра. Я думал, что где-то читал, что можно обрабатывать только строки/целые числа? Вот MapRoute:

        routes.MapRoute(
            "SearchResults",
            "Drivers/Index/{formCollection}/{page}",
            new { controller = "Drivers", action = "Index", formCollection = "", page = "" }
        );

Я полностью что-то упустил или есть способ справиться с этим? Я знаю, что могу просто использовать jquery/ajax для отправки строки, содержащейся в списке поиска, но я не хочу этого делать, потому что позже я планирую добавить флажки в качестве средства фильтрации поиска и т. д.

Я пробовал несколько разных способов установки значения formCollection, включая создание нового FormCollection, который добавляет searchBox, просто передавая строки и т. д.


person Darcy    schedule 24.02.2010    source источник
comment
Когда вы нажимаете «Далее», это просто вызов HttpGet из результата действия Index?   -  person Jack Marchetti    schedule 25.02.2010
comment
Он вызывает другой имеющийся у меня индекс ActionResult, который не принимает никаких параметров. (public ActionResult Index() { return View(); я думаю, что он никогда не вызывается, потому что это FormCollection, который нельзя использовать для маршрутной ссылки. Я думаю, что это должна быть строка или целое число. }   -  person Darcy    schedule 25.02.2010


Ответы (1)


Аргумент FormCollection в действии не является проблемой. Это всегда будет работать.

Однако он абсолютно не подходит к вашему маршруту! Просто избавьтесь от этого, и вы, вероятно, решите проблему. Элементы формы не входят в URI, и в маршруте должны находиться только данные из URI.

Однако это не то, как я бы написал эту сигнатуру действия. Я бы предложил:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string searchBox, int? page)
{
    var results = resultsRepository.GetResults();

    var paginatedResults = new PaginatedList<Driver>(results, page ?? 0, pageSize);

    return View(paginatedResults);
}

Наконец: в этом случае вы не должны возвращать View из POST. Это вызовет странное поведение пользователя; например, когда они нажимают кнопку «Обновить», их браузер предупредит их о повторной отправке формы.

Вы должны либо:

  1. Используйте GET, а не POST для результатов поиска.
  2. Перенаправление вместо возврата представления.

Лично я бы выбрал первое.

person Craig Stuntz    schedule 25.02.2010
comment
Ну, я должен использовать POST, так как действие Index перегружено (первое возвращает представление, а второе возвращает то же представление, но разбитое на страницы с результатами поиска). Когда вы говорите удалить его из маршрута, вы имеете в виду, что он будет выглядеть так?: route.MapRoute(SearchResults, Drivers/Index/{page}, new {controller = Drivers, action = Index, page = } ); Когда я это делаю, вместо этого вызывается ActionResult Index(). (у меня он выше всех остальных маршрутов на всякий случай) - person Darcy; 25.02.2010
comment
GET против POST имеет далеко идущие последствия и не должен использоваться для разрешения перегрузок! В любом случае вам нужно только одно действие — когда searchBox имеет значение null/пусто, а page не имеет значения, верните результаты без разбивки на страницы. Если Index не вызывается при исправлении маршрутизации, значит, у вас есть другие проблемы, не упомянутые здесь. FormCollection никогда не должен быть в маршруте! - person Craig Stuntz; 25.02.2010