DropDownList For unobtrusive verification Required Do not get the right attributes

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.

+6
source share
3 answers

Just use an integer with a null value in the property to which you are binding the drop-down list to your view model:

 [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] [Display(Name = "Some Choice")] public int? SomeChoice { get; set; } 

Also, in order to get proper unobtrusive HTML5 data attributes, the dropdown menu must be inside the form:

 @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, new { @class = "label" }) @Html.DropDownListFor( model => model.SomeChoice, Model.ListOfChoices, "Select..." ) @Html.ValidationMessageFor(model => model.SomeChoice) </div> <button type="submit">OK</button> } 

You will also notice that I got rid of the ViewBag (which I just can not stand) and replaced it with the corresponding property on your view model, which will contain possible options for the drop-down list.

+5
source

I had the same problem. And noticed that this happens when dropDownList is populated from ViewBag or ViewData. If you write @ Html.DropDownListFor (model => model.SomeChoice, Model.SomeChoice, "Select ..."), as in the above example, the validation attributes will be written.

+3
source

For those here who are looking for the same behavior in the Kendo drop-down list, add β€œrequired” to your code.

 @(Html.Kendo().DropDownListFor(m => m) .Name("FeatureId").BindTo((System.Collections.IEnumerable)ViewData[CompanyViewDataKey.Features]) .DataValueField("Id") .DataTextField("Name") .OptionLabel("--Select--") .HtmlAttributes(new { title="Select Feature", required="required"}) 

)

The [Required] attribute in the viewmodel did not work for me, but the addition is higher in the Htmlattributes. Hope this helps someone.

0
source

Source: https://habr.com/ru/post/899651/


All Articles