ASP.NET Core で、View から Controller に Post メソッドでデータを渡す際、配列やリストはどう渡せばいいか試してみました。
環境
- Visual Studio 2017
- ASP.NET Core 2.2
プリミティブ型の場合
Controller で以下のような値を受け取りたいとします。
[HttpPost]
public IActionResult PostTest2(string[] names)
{
// Do something
return View();
}
View は以下のようになります。
<form asp-controller="Home" asp-action="PostTest">
<table class="table">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < 5; i++)
{
<tr>
<td><input type="text" class="form-control" name="names"></td>
</tr>
}
</tbody>
</table>
<input type="submit" class="btn btn-primary" />
</form>
name
に引数名を指定することで、配列やリストに順に格納されて渡されます。
複合型の場合
クラスなどの場合、上記のように渡すことはできませんでした。
例として、View から Controller へ、以下のようなモデルを渡してみます。
public class SampleViewModel
{
public List<Person> Persons { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Controller は以下のような感じで普通に受け取ります。
public class HomeController : Controller
{
[HttpPost]
public IActionResult PostTest(SampleViewModel vm)
{
return View(vm);
}
}
肝心の View ですが、以下のようになります。
@model SampleViewModel
<form asp-controller="Home" asp-action="PostTest">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < 5; i++)
{
<tr>
<td><input type="text" class="form-control" asp-for="@Model.Persons[i].Name"></td>
<td><input type="text" class="form-control" asp-for="@Model.Persons[i].Age"></td>
</tr>
}
</tbody>
</table>
<input type="submit" class="btn btn-primary" />
</form>
大事なのは、asp-for="@Model.Persons[i].Name"
の部分でしょうか。
いろいろ試してみたのですが、どうやらインデックスまで指定して渡す必要があるようです。
今回 Persons
は List
として定義していますが、IEnuemrable
では渡せませんでした。
配列や IReadOnlyList
などは OK でした。
もしインデックスを指定せずにできるやり方があるならば教えていただきたいです。
尚、上記は for
で 5 回まわしているので、Contoller 側で受け取った時には要素数が 5 で固定になります。
サンプルとしては以上ですが、入力欄が動的に変わったりする場合などはインデックスを調整するなど一工夫する必要がありそうです。