項目の IList をビューにバインドするパターンはありますか。HttpPost に問題があるようです。Phil Haack が素晴らしい記事を書いたことは知っていますが、それは時代遅れであり、MVC 4 で修正される可能性があると述べています。
3 に答える
これは、アイテムごとにフォームを表示し、さまざまなプロパティに入力する必要がある場合の方法です。本当に私がやろうとしていることに依存します。
ViewModelは次のようになります。
public class MyViewModel
{
public List<Person> Persons{get;set;}
}
ビュー(もちろんBeginFormを使用):
@model MyViewModel
@for( int i = 0; i < Model.Persons.Count(); ++i)
{
@Html.HiddenFor(m => m.Persons[i].PersonId)
@Html.EditorFor(m => m.Persons[i].FirstName)
@Html.EditorFor(m => m.Persons[i].LastName)
}
アクション:
[HttpPost]public ViewResult(MyViewModel vm)
{
...
ポストバックでは、入力が利用可能なプロパティのみが値を持つことに注意してください。つまり、Personに.SSNプロパティがある場合、それはフォームのフィールドではなかったため、postアクションでは使用できません。
MVCのモデルバインディングが機能する方法では、連続するIDのみが検索されることに注意してください。したがって、条件付きでアイテムを非表示にするこのようなことを行うと、5番目のアイテムの後にデータがバインドされなくなります。これは、IDにギャップが発生すると、バインドが停止するためです。10人がいたとしても、ポストバックの最初の4人しか取得できません。
@for( int i = 0; i < Model.Persons.Count(); ++i)
{
if(i != 4)//conditionally hide 5th item,
{ //but BUG occurs on postback, all items after 5th will not be bound to the the list
@Html.HiddenFor(m => m.Persons[i].PersonId)
@Html.EditorFor(m => m.Persons[i].FirstName)
@Html.EditorFor(m => m.Persons[i].LastName)
}
}
クリーンな解決策は、リストを処理するジェネリック クラスを作成することです。そのため、必要になるたびに別のクラスを作成する必要はありません。
public class ListModel<T>
{
public List<T> Items { get; set; }
public ListModel(List<T> list) {
Items = list;
}
}
ビューを返すときは、次のことを行うだけです。
List<customClass> ListOfCustomClass = new List<customClass>();
//Do as needed...
return View(new ListModel<customClass>(ListOfCustomClass));
次に、モデルでリストを定義します。
@model ListModel<customClass>
そして行く準備ができました:
@foreach(var element in Model.Items) {
//do as needed...
}
〜コントローラー
namespace ListBindingTest.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
List<String> tmp = new List<String>();
tmp.Add("one");
tmp.Add("two");
tmp.Add("Three");
return View(tmp);
}
[HttpPost]
public ActionResult Send(IList<String> input)
{
return View(input);
}
}
}
〜強く型付けされたインデックスビュー
@model IList<String>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
@using(Html.BeginForm("Send", "Home", "POST"))
{
@Html.EditorFor(x => x)
<br />
<input type="submit" value="Send" />
}
</div>
</body>
</html>
〜強く型付けされた送信ビュー
@model IList<String>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Send</title>
</head>
<body>
<div>
@foreach(var element in @Model)
{
@element
<br />
}
</div>
</body>
</html>
これがあなたがしなければならなかったすべてです、彼のMyViewModelモデルをIListに変更してください。