2010-02-24 4 views
0

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

<% 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); 
    } 

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

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

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

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

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

+0

Когда вы нажимаете «Далее», это просто вызов HttpGet из результата action Index? –

+0

Он вызывает другой индекс ActionResult, который у меня нет, который не принимает никаких параметров. (public ActionResult Index() { return View(); Я думаю, что он никогда не вызывается, потому что его FormCollection не может использоваться для маршрутизации. Я думаю, что это должна быть строка или int. } – Darcy

ответ

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. Перенаправление вместо возврата.

Я бы выбрал первый, лично.

+0

Ну, я должен использовать POST, поскольку действие индекса перегружено (первый возвращает представление, а второй возвращает тот же вид, но с разбивкой на результаты поиска). Когда вы говорите, удалить его из маршрута, вы имеете в виду, так это будет выглядеть следующим образом ?: routes.MapRoute ( "SearchResults", "Drivers/Index/{страница}", новый {контроллер = " Драйверы ", action =" Index ", page =" "} ); Когда я это делаю, вместо этого вызывается индекс ActionResult(). (На всякий случай у меня есть все остальные маршруты) – Darcy

+1

'GET' v.' POST' имеет * далеко идущие * последствия и * не должен * использоваться для разрешения перегрузки! В любом случае вам нужно только одно действие - когда 'searchBox' имеет значение null/empty и' page' не имеет значения, верните не-разбитые страницы. Если «Указатель» не вызывается, когда вы исправляете свою маршрутизацию, тогда у вас есть другие проблемы, не упомянутые здесь. 'FormCollection' должен ** никогда ** не быть в пути, когда-либо! –