actionresult は、routelink によって呼び出されません。フォームコレクションが犯人?
-
22-09-2019 - |
質問
私は 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);
}
ここまでは順調ですね。単語を入力して送信ボタンを押すと、Index が呼び出され、それに応じてデータベースが返されます。ul には結果が入力され、pageSize を超える結果 (私の場合は 10) がある場合、[次へ] リンクが表示されます。
「次へ」をクリックすると、デフォルトのページが読み込まれます。ページネーションなどはありません。それは、私の Index ActionResult がパラメータとして FormCollection を持っているという事実と関係があると確信しています。文字列/整数のみを処理できるとどこかで読んだ気がします。マップルートは次のとおりです。
routes.MapRoute(
"SearchResults",
"Drivers/Index/{formCollection}/{page}",
new { controller = "Drivers", action = "Index", formCollection = "", page = "" }
);
何かが完全に欠けているのでしょうか、それともこれに対処する方法はありますか?jquery/ajax を使用して検索リストボックスに含まれる文字列を送信できることはわかっていますが、後で検索をフィルタリングする手段としてチェックボックスを追加する予定なので、それは行いません。
searchBox を追加する新しい FormCollection を作成する、文字列を渡すだけなど、formCollection の値を設定するいくつかの異なる方法を試しました。
解決
の 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
この場合。これにより、ユーザーに奇妙な動作が発生します。たとえば、更新を押すと、ブラウザはフォームの再送信について警告します。
次のいずれかを行う必要があります。
- 使う
GET
, ではありませんPOST
検索結果用。 - ビューを返す代わりにリダイレクトします。
個人的には最初を選びます。