我是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;
}
现在,当所有文本框都已创建,并且当第一个循环迭代文本框显示一条验证消息时,它将自动显示在另一个文本框的前面,这是在第二次循环迭代时创建的。
请告诉我哪里出错了。
答案 0 :(得分:9)
问题是因为您在TextBoxFor
和ValidationMessageFor
中使用的表达式,MVC使用该表达式为字段创建字符串名称并从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
,而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);
}