4

私は MVC Razor の初心者で、テキスト ボックスに検証メッセージを実装したいと考えています。ここでは、次のようにテキストボックスを動的に作成しています。

コードを表示:

foreach (var items in (IEnumerable<System.Data.DataRow>)Model.UsersOfList)
{

  @Html.TextBoxFor(m => m.LoginNameOfLoginInfoTab, new { @class = "textBox_LoginInfoAndPermission", @value = (Model.LoginNameOfLoginInfoTab = items["UserName"].ToString()), @id = ("txtUserLoginName" + Model.UsernameOfLoginInfoTab.Trim()) })

  @Html.ValidationMessageFor(m => m.LoginNameOfLoginInfoTab, null, new { @class = "ErrorMessage" })

  @Html.TextBoxFor(m => m.UsernameOfLoginInfoTab, new { @class = "textBox_LoginInfoAndPermission", @value = (Model.UsernameOfLoginInfoTab = items["FirstName"].ToString()), @id = ("txtUserName" + Model.UsernameOfLoginInfoTab.Trim()) })

  @Html.ValidationMessageFor(m => m.UsernameOfLoginInfoTab, null, new { @class = "ErrorMessage" })


}

モジュールでは、次のように検証用のコードを記述しました。

[Required (ErrorMessage="*")]
    public string UsernameOfLoginInfoTab
    {
        get;
        set;
    }


   [Required(ErrorMessage = "*")]
    public string LoginNameOfLoginInfoTab
    {
        get;
        set;
    }

すべてのテキストボックスが作成され、1 つの検証メッセージが最初のループ反復テキストボックスに表示されると、2 番目のループ反復で作成される別のテキストボックスの前にも自動的に表示されます。

何がうまくいかないのか教えてください。

4

1 に答える 1

9

問題は、フィールドの文字列名を作成し、からの検証メッセージを検索するために MVC によって使用されるTextBoxForとで使用している式が、ループの反復全体で常に同じであるためです。ValidationMessageForModelState

ここでのアプローチには少し欠陥があるように見えるので、私の答えはより包括的です。

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 が生成されます ( 0name と 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);

}
于 2012-11-06T10:44:57.393 に答える