如何使用DataAnnotation验证dropdownlist?

时间:2015-06-28 12:30:21

标签: asp.net-mvc-4 data-annotations

我需要你的帮助,我在使用AdataAnnotation进行验证时遇到问题

我正在尝试使用它来验证下拉列表,但它存在一些问题

这是我的代码

  

查看方

while (!_taskCodeQueue.empty()) {
//    ^^^ also fixed condition
    _taskQueue.push((_taskStore.find(_taskCodeQueue.front()))->second);
    _taskCodeQueue.pop();
}
  

控制器端

        @using (Html.BeginForm("addNewProject", "Activities", FormMethod.Post))
        {
            @Html.AntiForgeryToken()


            @Html.ValidationMessage("ProjectName")
            <h3>Project Name: </h3>
            @Html.TextBox("ProjectName", null,  new { @class = "text_field"} )

            @Html.ValidationMessage("ProjectOwner")
            <h3>Project Owner: </h3>
            @Html.DropDownList("ProjectOwner", (SelectList)ViewBag.Customers, new { @class = "text_field" })

            @Html.ValidationMessage("Description")
            <h3>Description: </h3>
            @Html.TextArea("Description", new { @class = "text_area"})

            @Html.ValidationMessage("Department")
            <h3>Departments: </h3>
            @Html.DropDownList("Department", (SelectList)ViewBag.Departments, new { @class = "list" })

            @Html.ValidationMessage("Region")
            <h3>Regions: </h3>
            @Html.DropDownList("Region", (SelectList)ViewBag.Regions, new { @class = "list" })

            <input type="submit" value="Add" class="submit" />
        }
  

数据持有人

    public ActionResult NewProject()
    {
        List<SelectListItem> list = new List<SelectListItem>();

        list.Add(new SelectListItem() { Value = "0", Text = "Choose ..." });

        list.Add(new SelectListItem() { Value = "1", Text = "First" });

        list.Add(new SelectListItem() { Value = "2", Text = "Second" });

        list.Add(new SelectListItem() { Value = "3", Text = "Third" });

        ViewBag.Departments = new SelectList(list, "Value", "Text");
        ViewBag.Regions = new SelectList(list, "Value", "Text");
        ViewBag.Customers = new SelectList(list, "Value", "Text");

        return View();
    }
    public ActionResult addNewProject(Project newProject)
    {
        if (ModelState.IsValid)
        {

            return RedirectToAction("index", "Home");
        }
        else
        {
            return View("NewProject", newProject);
        }
    }

2 个答案:

答案 0 :(得分:8)

您的代码存在两个主要问题。

首先,您尝试将<select>绑定到List<SelectListItem>的属性,但<select>只回发一个不能绑定到{List<SelectListItem>的值类型1}}所以属性为null,验证失败。您的属性需要(例如)typeof intstring

其次,您手动添加SelectListItem Value ="0"Text = "Choose ...",这意味着即使您更正了第一个问题,如果用户选择了第一个选项(&#34;选择...&#34;),您的模型将有效,因为&#34; 0&#34;是一个有效的值。

你的班级需要

public class Project : DataHolder
{
  ....

  [Display(Name = "Project Owner")]
  [Required(ErrorMessage = "Please select a project owner")]
  public int ProjectOwner { get; set; }

  public List<SelectListItem> ProjectOwnerList { get; set; }

  .... // ditto for Department and Region
}

然后在控制器中

public ActionResult NewProject()
{
  List<SelectListItem> list = new List<SelectListItem>();
  list.Add(new SelectListItem() { Value = "1", Text = "First" });
  list.Add(new SelectListItem() { Value = "2", Text = "Second" });
  list.Add(new SelectListItem() { Value = "3", Text = "Third" });
  // Initialize the model
  Project model = new Project();
  model.ProjectOwnerList = list;
  model.DepartmentList = list;
  model.RegionList = list;
  return View(model); // always return a model even if its just a default new instance!
}

请注意,您的模型包含List<SelectListItem>的属性,因此请勿使用ViewBag,并且在任何情况下,DropDownList()方法仅需要IEnumerable<SelectListItem>作为其第二个参数,因此从SelectList创建新的List<SelectListItem>只是不必要的额外开销

然后在视图中

@Html.LabelFor(m => m.ProjectOwner)
@Html.DropDownListFor(m => m.ProjectOwner, Model.ProjectOwnerList, "Choose...")
@Html.ValidationMessageFor(m => m.ProjectOwner)

请注意,DropDownListFor()的第3个参数会添加labelOption null值 - <option value>Choose...</option> - ,因此如果选中它,您现在将收到错误消息该模型无效。

假设用户选择了"Second",那么当您回发时,ProjectOwner的值将为2

答案 1 :(得分:0)

之前的答案是一个非常好的答案但仍有一个问题,当它无法验证其中一个字段时会出现问题,它会将您重定向到同一页面,现在您将遇到问题,因为在您的代码中在这种情况下没有启动任何新列表,因此您将获得错误,因为对象中列表的值为空。

您的代码可以像这样修改以解决此问题。

  

将其添加到您的代码中进行组织,您可以根据需要添加多个GetList方法。

List<SelectListItem> GetList()
{
    List<SelectListItem> list = new List<SelectListItem>();

    list.Add(new SelectListItem() { Value = "", Text = "Choose ..." });
    list.Add(new SelectListItem() { Value = "1", Text = "First" });
    list.Add(new SelectListItem() { Value = "2", Text = "Second" });
    list.Add(new SelectListItem() { Value = "3", Text = "Third" });

    return list;
}
  

将addNewProject方法修改为这样。

public ActionResult addNewProject(Project newProject)
{
    if (ModelState.IsValid)
    {

        return RedirectToAction("index", "Home");
    }
    else
    {

        newProject.ProjectOwnerList = GetList();
        newProject.DepartmentList = GetList();
        newProject.RegionList = GetList();

        return View("NewProject", newProject);
    }
}

请注意,如果使用DataAnnotation客户端验证,您将不会注意到此问题,但即使您使用客户端验证,您也必须解决该问题