次のようなモデルを使用しているmvcアプリケーションがあります。
public class BlockedIPViewModel
{
public string IP { get; set; }
public int ID { get; set; }
public bool Checked { get; set; }
}
これで、次のようなリストをバインドするビューができました。
@model IEnumerable<OnlineLotto.Web.Models.BlockedIPViewModel>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
}
@foreach (var item in Model) {
<tr>
<td>
@Html.HiddenFor(x => item.IP)
@Html.CheckBoxFor(x => item.Checked)
</td>
<td>
@Html.DisplayFor(modelItem => item.IP)
</td>
</tr>
}
<div>
<input type="submit" value="Unblock IPs" />
</div>
これで、送信ボタンからアクションを受け取るコントローラーができました。
public ActionResult BlockedIPList(IEnumerable<BlockedIPViewModel> lstBlockedIPs)
{
}
しかし、コントローラーアクションに来たときにlstBlockedIPsにnull値を取得しています。ここでチェックボックスの状態を取得する必要があります。助けてください。
代わりにリストを使用して、foreach
ループをfor
ループに置き換えます。
@model IList<BlockedIPViewModel>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@for (var i = 0; i < Model.Count; i++)
{
<tr>
<td>
@Html.HiddenFor(x => x[i].IP)
@Html.CheckBoxFor(x => x[i].Checked)
</td>
<td>
@Html.DisplayFor(x => x[i].IP)
</td>
</tr>
}
<div>
<input type="submit" value="Unblock IPs" />
</div>
}
または、エディターテンプレートを使用することもできます。
@model IEnumerable<BlockedIPViewModel>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.EditorForModel()
<div>
<input type="submit" value="Unblock IPs" />
</div>
}
そして、コレクションの各要素に対して自動的にレンダリングされるテンプレート~/Views/Shared/EditorTemplates/BlockedIPViewModel.cshtml
を定義します。
@model BlockedIPViewModel
<tr>
<td>
@Html.HiddenFor(x => x.IP)
@Html.CheckBoxFor(x => x.Checked)
</td>
<td>
@Html.DisplayFor(x => x.IP)
</td>
</tr>
コントローラーでnullを取得していた理由は、デフォルトのモデルバインダーがリストに正常にバインドすると予想する入力フィールドの命名規則を尊重しなかったためです。 following article
をお読みください。
それを読んだら、生成されたHTML(およびより具体的には入力フィールドの名前)を私の例とあなたのもので見てください。次に、比較すると、なぜあなたが動作しないのかがわかります。