Asp.net mvc ModelState validity when using dropdow

2020-07-18 04:41发布

问题:

ModelState.IsValid always false because I use a dropdownlist in the form that I want to submit and I get this exception:

The parameter conversion from type 'System.String' to type 'System.Web.Mvc.SelectListItem' failed because no type converter can convert between these types


Model:

public class NewEmployeeModel
{
    [Required(ErrorMessage = "*")]
    [Display(Name = "Blood Group")]
    public IEnumerable<SelectListItem> BloodGroup { get; set; }
}

View:

<div class="form-group">
   @Html.LabelFor(m => m.BloodGroup, new { @class = "control-label col-md-3" })
   <div class="col-md-4">        
      @Html.DropDownListFor(m => m.BloodGroup, Model.BloodGroup, "Please Select", new { @class = "form-control" })
   </div>
</div>

Controller:

 [HttpPost]
    public ActionResult Employee(NewEmployeeModel model)
    {
        var errors = ModelState
            .Where(x => x.Value.Errors.Count > 0)
            .Select(x => new { x.Key, x.Value.Errors })
            .ToArray();

        if (!ModelState.IsValid)
        {
            ModelState.AddModelError("Employee", "Model is Not Valid");
            return View("Employee", model);
        }
        else
        {
            return null;
        }
    }

回答1:

This is not how you use a SelectList

You need another model property to hold the selected value of the BloodGroup:

public class NewEmployeeModel
{
    [Required(ErrorMessage = "*")]
    [Display(Name = "Blood Group")]
    public int BloodGroup { get; set; }

    public IEnumerable<SelectListItem> BloodGroups { get; set; }
}

<div class="form-group">
   @Html.LabelFor(m => m.BloodGroup, new { @class = "control-label col-md-3" })
   <div class="col-md-4">        
      @Html.DropDownListFor(m => m.BloodGroup, Model.BloodGroups, "Please Select", new { @class = "form-control" })
   </div>
</div>

You are not posting all of the items in the dropdown list, you are only posting the value of the selected item. In my example I'm assuming it's an int (primary key value perhaps).

If validation fails on the POST, you need to repopulate those values again:

if (!ModelState.IsValid)
{
    model.BloodGroups = GetBloodGroups();

    ModelState.AddModelError("Employee", "Model is Not Valid");
    return View("Employee", model);
}