DropDownListFor Ненавязчивая проверка требуется Не получить правильные атрибуты - PullRequest
6 голосов
/ 20 октября 2011

Этот вопрос похож, но принятый ответ решает его на стороне сервера, меня интересуют решения на стороне клиента.

Учитывая эту 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; }    
}

и бритва

<div>
@Html.LabelFor(model => model.SomeChoice, new { @class = "label" })
@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...")
@Html.ValidationMessageFor(model => model.SomeChoice)
</div>

и предположим, что ViewBag.SomeChoice содержит список выбора

Отрендеренный html не получает data-val = "true" data-val-required = "Я ТРЕБУЮ ВЫ ВЫБЕРИТЕ ВЫБОР!" атрибуты в нем, такие как @ Html.EditorFor (model => model.Keyword) или @ Html.TextBoxFor будут отображать.

Почему?

Добавление класса = "required" к нему, вот так

@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...", new { @class = "required" })

, который использует семантику класса jQuery Validation и блокирует при отправке, но не отображает сообщение. Я могу делать такие вещи

@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!" } })

Который поместит туда правильные атрибуты, блокирует отправку и показывает сообщение, но не использует сообщение RequiredAttribute ErrorMessage, которое у меня есть в моей ViewModel

Так кто-нибудь написал DropDownListFor, который ведет себя как другие HtmlHelpers в отношении проверки?

EDIT Вот мой ТОЧНЫЙ код

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

А вот приведенный код

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

Он отправляет обратно моему контроллеру ... этого не должно происходить

Ответы [ 3 ]

5 голосов
/ 20 октября 2011

Просто используйте обнуляемое целое число для свойства, с которым вы связываете раскрывающийся список в вашей модели представления:

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

Кроме того, чтобы получить надлежащие ненавязчивые атрибуты данных HTML5 *, раскрывающийся список должен быть внутри формы:

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

Также вы заметите, что я избавился от ViewBag (который я просто не могу выдержать) и заменил его соответствующим свойством в вашей модели представления, которое будет содержать возможные варианты для раскрывающегося списка.

3 голосов
/ 13 января 2012

У меня была такая же проблема.И заметил, что это происходит, когда dropDownList заполняется из ViewBag или ViewData.Если вы напишите @ Html.DropDownListFor (model => model.SomeChoice, Model.SomeChoice, "Select ..."), как в приведенном выше примере, атрибуты проверки будут записаны.

0 голосов
/ 12 октября 2017

Те, кто ищет подобное поведение в выпадающем списке Kendo, пожалуйста, добавьте «обязательный» в свой код.

@(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"})

)

Атрибут [Обязательный] в viewmodel у меня не сработал, но добавление вышеупомянутого в Htmlattributes сработало. Надеюсь, это кому-нибудь поможет.

...