繁体   English   中英

具有强类型视图的MVC验证错误

[英]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>
   <% } %>  

提交此表格后,我要检查是否同时填写了FirstNameLastName (即非零长度)。

在我的控制器中,我有:

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
}

不幸的是,此代码逻辑产生一个错误,指出没有找到JobRoleCourses对象。

如果我删除了下拉列表和复选框,则一切正常。

问题似乎是当我返回View该视图期望dropwdownlist和复选框所用的对象(这很明智,因为这就是我的View代码中的内容)

我该如何克服这个问题?

我考虑过的事情:

  1. 在我的控制器中,我可以创建一个JobRoleList对象和Course对象,以传递给View,以便它具有要渲染的对象。 这样做的问题是它将覆盖用户已经进行的所有下拉列表/复选框选择。
  2. 在我的控制器方法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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM