ASP.NET MVCページング-複雑な型をコントローラーに戻す?
-
05-07-2019 - |
質問
現在、ユーザーが検索データを入力し、結果のリストを取得し、各アイテムを表示できる、合理的なシンプルなMVCアプリを開発中です。すべて順調に進んでいますが、実装を試みています。ページングしても問題があります。
検索フォームはHTTP GETを使用して、次のアクションを要求します:
public ActionResult Results(PropertySearchData data, int? page)
{
...
IEnumerable<Property> search = mService.SearchProperties(data);
ViewData["SearchData"] = data;
return View("Results", "Site", search.ToPagedList(page ?? 0, 20));
...
}
ここから、ビューに渡されたIEnumerableコレクションから結果のテーブルを作成します。さらに、ユーザーが別のページをリクエストしたときに渡すことができるように、ViewDataを使用して検索パラメーターを保持しました。
たとえば、最初のページに移動するには、次のようなものを使用します:
Html.ActionLink("First", "Results", new { data = ViewData["SearchData"], page = 1 })
ただし、このリンクが生成されると、リンクは次のようになります
/Results?data=PropertySearchData&page=1
'page'パラメーターを完全に削除し、ViewData [&quot; SearchData&quot;]をルート値として渡すと、リンクが希望どおりに生成されます(つまり、PropertySearchDataの各メンバーがクエリ文字列として渡されます)これは、モデルバインディングが単一のタイプを指定した場合にのみ正しく機能するためです。
これが機能しない理由については、いくつかの理由がわかります。私が問題を抱えているのは、私がやろうとしていることを「いい」方法で解決することです。私はここで重要な理解を欠いているに違いないことを知っているので、これにアプローチする方法についての指針を得ることができれば非常に感謝されます。
本当にHTTP GETに固執したいことに注意してください(これは検索結果ページであるため)。
ありがとう!
解決
問題は、ヘルパーメソッドが、与えられたものから何かを生成するのが最善であり、データとページの2つのプロパティを持つオブジェクトであるということです。
ページ番号を取得するには、ルート値ディクショナリ(おそらく内部で行われることです)を使用し、IDictionaryを受け入れるオーバーライドを使用できます:-
//In some HtmlHelper extension method or something
var searchCriteria = new RouteValueDictionary(ViewData["searchData"]);
searchCriteria.Add("page", 1);
return Html.ActionLink("First", "Results", searchCriteria)
他のヒント
data
または ViewData [&quot; SearchData&quot;]
は PropertySearchData
のインスタンスであるため、 Html.ActionLink
は、その上で ToString()
を呼び出していますが、期待する結果は得られません。
HtmlHelper拡張メソッドを作成することは、これを解決する最良の方法ではありません。一般的な機能は追加されず、より多くの(視覚的な)混乱が発生します...
Html.ActionLinkのrouteValuesオーバーロードでは、オブジェクトまたはRouteValueCollection(IDictionary)が必要です。オブジェクトオーバーロードを使用しています(新しい{}コンストラクターは匿名オブジェクトであるため)。
次を使用して、正しいrouteValuesパラメーターを作成できます。
new RouteValueCollection(ViewData["SearchData"]) { { "page", 1 } }
これにより、現在の検索データで新しいRouteValueCollectionが初期化され、新しい値で「ページ」キーが追加されます(検索データに存在する場合は上書きされます)。