【问题标题】:DropDownListFor Unobtrusive Validation Required Not getting correct attributesDropDownListFor Unobtrusive Validation required 没有得到正确的属性
【发布时间】:2011-12-11 08:28:09
【问题描述】:

This Question 类似,但接受的答案在服务器端解决,我对客户端解决方案感兴趣。

给定这个 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="I DEMAND YOU MAKE A CHOICE!"其中的属性,如 @Html.EditorFor(model => model.Keyword) 或 @Html.TextBoxFor 将呈现。

为什么?

像这样添加 class= "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!" } })

这将把正确的属性放在那里,并阻止提交并显示消息,但没有利用我的 ViewModel 上的 RequiredAttribute ErrorMessage

那么有没有人写过一个 DropDownListFor,它在验证方面的行为与其他 HtmlHelper 一样?

编辑 这是我的确切代码

在 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();
    }

关于.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>

它回发给我的控制器...这不应该发生

【问题讨论】:

    标签: asp.net-mvc-3 validation razor html-helper


    【解决方案1】:

    只需在视图模型上将下拉列表绑定到的属性上使用可为空的整数:

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

    此外,为了获得适当的不显眼的 HTML5 data-* 属性,下拉菜单必须在表单内:

    @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(我简直无法忍受)并用您的视图模型上的相应属性替换它,该属性将包含下拉菜单的可能选项。

    【讨论】:

    • 我将 int 设为可空,但仍无法在控件中写入数据验证元素
    【解决方案2】:

    我遇到了同样的问题。并注意到当从 ViewBag 或 ViewData 填充 dropDownList 时会发生这种情况。如果你会写 @Html.DropDownListFor(model => model.SomeChoice, Model.SomeChoice, "Select...") 如上面的示例验证属性将被写入。

    【讨论】:

    • 这太令人失望了。我将模型中的所有选择列表提取到 ViewData 中,因此可以通过基于 UIHInt 的属性中的列表名称访问该列表。
    • 令人失望的信息,但知道有用。可悲的是,现实世界很少总是被强类型化。
    【解决方案3】:

    那些在剑道下拉列表中寻找相同行为的人,请在您的代码中添加“必需”。

    @(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 中的 [Required] 属性对我不起作用,但在 Htmlattributes 中添加上述属性可以。希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      相关资源
      最近更新 更多