This question is similar, but the accepted answer solves it on the server side, I'm interested in solutions on the client side.
Given this ViewModel
public class MyViewModel { public string ID { get; set; } [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] [Display(Name = "Some Choice")] public int SomeChoice{ get; set; } [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] [Display(Name = "Keyword")] public string Keyword { get; set; } }
and razor
<div> @Html.LabelFor(model => model.SomeChoice, new { @class = "label" }) @Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...") @Html.ValidationMessageFor(model => model.SomeChoice) </div>
and suppose ViewBag.SomeChoice contains a select list
The submitted html does not receive data-val = "true" data-val-required = "I ASK YOU WILL MAKE A CHOICE!" attributes in it like @ Html.EditorFor (model => model.Keyword) or @ Html.TextBoxFor will display.
Why?
Adding a class to it = "required"
@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...", new { @class = "required" })
which uses the semantics of the jQuery Validation Java class and blocks to send, but does not display a message. I can do such things
@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...", new Dictionary<string, object> { { "data-val", "true" }, { "data-val-required", "I DEMAND YOU MAKE A CHOICE!" } })
Which puts the required attributes there, and blocks sending and shows the message, but does not use the RequiredAttribute ErrorMessage property that I have on my ViewModel
So did someone write a DropDownListFor that behaves like other HtmlHelpers with respect to validation?
EDIT Here is my EXACT code
In HomeController.cs
public class MyViewModel { [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] [Display(Name = "Some Choice")] public int? SomeChoice { get; set; } } public ActionResult About() { var items = new[] { new SelectListItem { Text = "A", Value = "1" }, new SelectListItem { Text = "B", Value = "2" }, new SelectListItem { Text = "C", Value = "3" }, }; ViewBag.SomeChoice = new SelectList(items,"Value", "Text"); ViewData.Model = new MyViewModel {}; return View(); }
About.cshtml
@using Arc.Portal.Web.Host.Controllers @model MyViewModel <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> @using (Html.BeginForm()) { <div> @Html.LabelFor(model => model.SomeChoice) @Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...") @Html.ValidationMessageFor(model => model.SomeChoice) </div> <button type="submit">OK</button> }
And here is the code rendering
<form action="/Home/About" method="post"> <div> <label for="SomeChoice">Some Choice</label> <select id="SomeChoice" name="SomeChoice"><option value="">Select...</option> <option value="1">A</option> <option value="2">B</option> <option value="3">C</option> </select> <span class="field-validation-valid" data-valmsg-for="SomeChoice" data-valmsg-replace="true"> </span> </div> <button type="submit">OK</button> </form>
He returns to my controller ... this should not be.