how to validate dropdownlist using the DataAnnotation?

巧了我就是萌 提交于 2019-12-08 00:19:50

问题


I need your help, I have a problem with the validation using AdataAnnotation

I am trying to validate a dropdown list using it but there is some problem with it

this is my code

View Side

        @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" />
        }

Controller Side

    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);
        }
    }

The Data Holder

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
namespace workflow.DataHolders
{
    public class Project : DataHolder
    {
        [Required(ErrorMessage = "This Field Is Required")]
        [StringLength(200, MinimumLength = 3, ErrorMessage = "Length Of The Title Should Be More Than 3 Letters")]
        public string ProjectName{ get; set; }

        [Required(ErrorMessage = "This Field Is Required")]
        public List<SelectListItem> ProjectOwner { get; set; }

        string Description { get; set; }

        [Required(ErrorMessage = "This Field Is Required")]
        public List<SelectListItem> Department { get; set; }

        [Required(ErrorMessage = "This Field Is Required")]
        public List<SelectListItem> Region { get; set; }


    }
}

回答1:


There are 2 main issues with you code.

First your trying to bind a <select> to a property which is List<SelectListItem>, but a <select> only posts back a single value type which can't be bound to List<SelectListItem> so the property is null and validation fails. Your properties need to be (for example) typeof int or string.

Secondly, your manually adding a SelectListItem with Value ="0" and Text = "Choose ..." which means that even if you correct the first issue, if the user selects the first option ("Choose ..."), your model will be valid because "0" is a valid value.

Your class needs to be

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
}

Then in the controller

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!
}

Note your model contains properties for List<SelectListItem> so don't use ViewBag, and in any case, the DropDownList() method only requires IEnumerable<SelectListItem> as its second parameter, so creating a new SelectList from List<SelectListItem> is just unnecessary extra overhead

Then in the view

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

Note that the 3rd parameter of DropDownListFor() adds a labelOption with a null value - <option value>Choose...</option> -, so if its selected, youu will now get an error message and the model will be invalid.

Assuming the user selects "Second", then when you post back, the value of ProjectOwner will be 2.




回答2:


The previous answer is a very good answer but still it has one problem, the problem appears when it fails to validate one of the fields it will redirect you to the same page and now you will have a problem because in your code you did not initiate any new list at that case so you will get Error because the values of the lists in the object are nulls.

your code could be modified like this to solve this problem.

Add this to your code to organize it and you could add more than one GetList method depending on your needs.

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;
}

Modify the addNewProject method to be like this.

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);
    }
}

Note that you will not notice this problem if you use the DataAnnotation Client Side Validation, but even if you use the Client Side validation you have to solve that problem



来源:https://stackoverflow.com/questions/31099817/how-to-validate-dropdownlist-using-the-dataannotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!