ASP.net MVC3 DropDownListFor int Required DataAnnotation

本秂侑毒 提交于 2019-12-25 09:36:35

问题


Is there a way to trigger client-side validation for the select list created by DropDownListFor? The select list that gets created by the helper doesn't seem to get the "data-val" or "data-val-required" attributes that text inputs get for client-side validation.

The validation does occur on the server-side when I check ModelState.IsValid, and the validation message is then displayed on the subsequent page load.

I set a default option of "Please Select..." on the list because I want the user to have to choose an option (as opposed to having it select the first item in the list).

My View Model:

public partial class ProvinceVM
{
    [Required]
    [Range(1, int.MaxValue)]
    public int CountryId { get; set; }
    [Required]
    [StringLength(16)]
    public string Abbreviation { get; set; }
    [Required]
    [StringLength(64)]
    public string Name { get; set; }
}

The code in the View:

<div class="editor-label">
    @Html.LabelFor(model => model.CountryId, "Country")
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryId, "Please Select...") 
    @Html.ValidationMessageFor(model => model.CountryId)
</div>

And my controller code:

[HttpPost]
public ActionResult Create(ProvinceEditVM provinceVM)
{
    if (ModelState.IsValid)
    {
        var province = new Province() { CountryId = provinceVM.CountryId.Value, Abbreviation = provinceVM.Abbreviation, Name = provinceVM.Name };
        _repo.Add<Province>(province);
        _repo.SaveChanges();
        return RedirectToAction("index");  
    }
    ViewBag.CountryId = new SelectList(_repo.GetQuery<Country>().OrderBy(x => x.Name), "CountryId", "Name", provinceVM.CountryId);
    return View(provinceVM);
}

Things I've already tried:

  • Making the View Model's CountryId property a nullable int (int?)
  • Removing the Range attribute for the CountryId property
  • Renaming the ViewBag.CountryId to something else (in case there were some conflict with the View Model's property name)

I can easily make the value required using jQuery, but I want to make sure I'm not overlooking something that is already built in; especially since further down the road I'd like to add localized culture error messages.


回答1:


This is a bug in unobtrusive validation of dropdownlists. MVC 3 RTM does not create unobtrusive validation for a collection of dropdownlists. See http://aspnet.codeplex.com/workitem/7629. The problem is that the code to build the unobtrusive validation makes a call WITHOUT reference to the metadata, which causes it to return a null value. The solution is to build your own HtmlHelper for DropDownListFor.

Look at the attached zip file for a workaround




回答2:


Was actually able to get it working by doing a combination of all three things I mentioned at the end of my post. Made the property on the View Model nullable, required, and had to rename the ViewBage.CountryId to something else (I renamed it to CountryList).

I figured it out by adding a SelectList property to my ProvinceVM to get it out of the ViewBag, then all of a sudden the data-val* attributes were showing up on the list.



来源:https://stackoverflow.com/questions/8550372/asp-net-mvc3-dropdownlistfor-int-required-dataannotation

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