[英]MVC validation error with strongly typed view
我有一个简单的表单,希望在提交表单时进行验证。 请注意,我已经删除了html,以方便查看
<%=Html.TextBox("LastName", "")%> //Lastname entry
<%=Html.ValidationMessage("LastName")%>
<%=Html.TextBox("FirstName", "")%>//Firstname entry
<%=Html.ValidationMessage("FirstName")%>
<%=Html.DropDownList("JobRole", Model.JobRoleList)%> //Dropdownlist of job roles
<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select
{ %>
<li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li>
<% } %>
提交此表格后,我要检查是否同时填写了FirstName
和LastName
(即非零长度)。
在我的控制器中,我有:
public ActionResult Submit(string FirstName, string LastName)
{
if (FirstName.Trim().Length == 0)
ModelState.AddModelError("FirstName", "You must enter a first name");
if (LastName.Trim().Length == 0)
ModelState.AddModelError("LastName", "You must enter a first name");
if (ModelState.IsValid)
{
//Update database + redirect to action
}
return View(); //If ModelState not valid, return to View and show error messages
}
不幸的是,此代码逻辑产生一个错误,指出没有找到JobRole
和Courses
对象。
如果我删除了下拉列表和复选框,则一切正常。
问题似乎是当我返回View
该视图期望dropwdownlist和复选框所用的对象(这很明智,因为这就是我的View代码中的内容)
我该如何克服这个问题?
我考虑过的事情:
JobRoleList
对象和Course
对象,以传递给View,以便它具有要渲染的对象。 这样做的问题是它将覆盖用户已经进行的所有下拉列表/复选框选择。 Submit
的参数中,我还可以捕获JobRoleList
对象和Course
对象以传递回View。 同样,不确定这是否会捕获用户已经选择的任何项目。 我做了很多谷歌搜索和阅读工作,但找不到很好的答案。 当我在书籍或在线上查看示例时(例如Nerddinner),所有验证示例都涉及带有TextBox输入的简单表单,并且似乎没有显示具有多个复选框和下拉列表的实例。
我错过了这里明显的东西吗? 在这种情况下,最佳做法是什么?
谢谢
最佳做法是接受特定于视图的模型。 您可能拥有一个共享模型,该模型既具有呈现页面所需的属性,又具有发布后所需的属性,或者具有用于呈现和接受发布参数的单独模型。 我通常使用共享模型,因为这意味着我可以简单地返回我收到的模型,并适当地重新填充生成菜单所需的任何数据(例如JobList和Courses)。 通常,我会有一个采用这种类型的模型并返回包含菜单属性的视图的方法。
public ActionResult JobsView( JobsViewModel model )
{
model.JobList = db.Jobs.Select( j => new SelectListItem
{
Text = j.Name,
Value = j.ID.ToString()
});
...
return View( model );
}
然后从需要使用这种类型的模型的视图的任何操作中调用此方法,以确保模型具有正确的菜单数据。
// on error, return the view
return JobsView( model );
使用模型时,还可以使用DataAnnotations装饰模型属性,并让模型绑定器为您进行验证,以及启用基于模型的客户端验证。 现有属性不支持的任何验证都可以通过创建自己的属性来实现,也可以在控制器操作中完成。
public class JobsViewModel
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public int JobRole { get; set; }
[ScaffoldColumn(false)]
public IEnumerable<SelectListItem> JobRoleList { get; set; }
...
}
public ActionResult Submit( JobsViewModel model )
{
if (ModelState.IsValid)
{
... convert model to entity and save to DB...
}
return JobsView( model );
}
然后在您的HTML中启用验证
...
<script type="text/javascript" src="<%= Url.Content( "~/scripts/MicrosoftMvcValidation.js" ) %>"></script>
<% Html.EnableClientValidation(); %>
... begin form...
<%=Html.TextBoxFor( m=> m.LastName )%>
<%=Html.ValidationMessageFor( m => m.LastName )%>
<%=Html.TextBoxFor( m=> m.FirstName )%>
<%=Html.ValidationMessageFor( m => m.FirstName )%>
<%=Html.DropDownListFor( m=> m.JobRole, Model.JobRoleList)%>
<% foreach (var record in Model.Courses) // Checkboxes of different courses for user to select
{ %>
<li><label><input type="checkbox" name="Courses" value="<%=record.CourseName%>" /><%= record.CourseName%></label></li>
<% } %>
在简单的MVC验证中,您应该传递强类型对象,即您的视图模型。
例:
public ActionResult Update(Employees employee)
{
if (employee.Name.Trim().Length == 0)
ModelState.AddModelError("Name", "Name is required.");
// ETC....
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.