問題は、フィールドの文字列名を作成し、からの検証メッセージを検索するために MVC によって使用されるTextBoxFor
とで使用している式が、ループの反復全体で常に同じであるためです。ValidationMessageFor
ModelState
ここでのアプローチには少し欠陥があるように見えるので、私の答えはより包括的です。
1) 表示しようとしている情報を構造的に表すビュー モデルを作成します。
ビュー モデルを修正します。
public class UserInfoViewModel
{
[Required (ErrorMessage="*")]
public string UserName { get; set; }
[Required(ErrorMessage = "*")]
public string LoginName { get; set; }
}
// I don't know if you actually need this or not, but your existing model may contain additional properties relevant to the view that I don't know about, so I'll keep it.
public class ListOfUsersViewModel
{
public IList<UserInfoViewModel> UsersOfList { get; set; }
}
アクションを修正します (ポイントを説明するためにここでこれを作成しています)。
public ActionResult ListOfUsers()
{
var users = GetUserDataRows(); // gets your collection of DataRows
var model = new ListOfUsersViewModel
{
UsersOfList = users.Select(row = new UserViewModel { UserName = row["FirstName"], LoginName = row["UserName"] }).ToList()
};
return View(model);
}
2) これで、ビュー内のユーザーを繰り返し処理し、検証メッセージを含む適切なフィールドを作成できます。
このビューを と呼びましょうListOfUsers.cshtml
。ビューに必要なものは何でも含めますが、for
代わりにループを使用してください。
@using(Html.BeginForm("ListOfUsers"))
{
<ul>
@for (var i = 0; i < Model.UsersOfList.Count; i++)
{
<li>
@Html.TextBoxFor(m.UsersOfList[i].LoginName, new {@class="textbox_LoginInfoAndPermission"})
@Html.ValidationMessageFor(m => m.UsersOfList[i].LoginName)
@Html.TextBoxFor(m.UsersOfList[i].UserName, new {@class="textbox_LoginInfoAndPermission"})
@Html.ValidationMessageFor(m => m.UsersOfList[i].UserName)
</li>
}
</ul>
<button type="submit">Submit changes</button>
}
これにより、各アイテムに対して次のような HTML が生成されます ( 0
name と id はコレクション内のユーザーのインデックスになります)。
<li>
<input type="text" id="UsersOfList_0_LoginName" name="UsersOfList[0].LoginName" value="..." />
<span class="field-validation-valid" data-valmsg-for="UsersOfList_0_LoginName" ... ></span>
<input type="text" id="UsersOfList_0_UserName" name="UsersOfList[0].UserName" value="..." />
<span class="field-validation-valid" data-valmsg-for="UsersOfList_0_UserName" ... ></span>
</li>
3) 送信された変更を受け取るアクションを作成します。このアクションは、送信された値を引数に自動的にバインドし、model
検証を行います。チェックするだけですModelState.IsValid
。
[HttpPost, ActionName("ListOfUsers")]
public ActionResult ListOfUsersPost(ListOfUsersViewModel model)
{
// at this point, model will be instantiated, complete with UsersOfList with values submitted by the user
if (ModelState.IsValid) // check to see if any users are missing required fields. if not...
{
// save the submitted changes, then redirect to a success page or whatever, like I do below
return RedirectToAction("UsersUpdated");
}
// if ModelState.IsValid is false, a required field or other validation failed. Just return the model and reuse the ListOfUsers view. Doing this will keep the values the user submitted, but also include the validation error messages so they can correct their errors and try submitting again
return View("ListOfUsers", model);
}