ASP.net MVC3 DropDownListFor int 必需的数据注释

发布于 2024-12-21 13:18:40 字数 1767 浏览 4 评论 0原文

有没有办法触发对 DropDownListFor 创建的选择列表的客户端验证?由帮助器创建的选择列表似乎没有获得文本输入为客户端验证而获得的“data-val”或“data-val-required”属性。

当我检查 ModelState.IsValid 时,验证确实发生在服务器端,然后验证消息将显示在后续页面加载中。

我在列表中设置了默认选项“请选择...”,因为我希望用户必须选择一个选项(而不是让它选择列表中的第一项)。

我的视图模型:

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

视图中的代码:

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

和我的控制器代码:

[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);
}

我已经尝试过的事情:

  • 使视图模型的 CountryId 属性成为可空 int (int?)
  • 删除 CountryId 属性的 Range 属性
  • 将 ViewBag.CountryId 重命名为某个内容否则(如果与视图模型的属性名称存在一些冲突)

我可以轻松地使用 jQuery 获取所需的值,但我想确保我不会忽略已经内置的内容;特别是因为我想进一步添加本地化文化错误消息。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妞丶爷亲个 2024-12-28 13:18:40

这是下拉列表的不显眼验证中的一个错误。 MVC 3 RTM 不会为下拉列表集合创建不引人注目的验证。请参阅http://aspnet.codeplex.com/workitem/7629。问题在于,构建不引人注目的验证的代码在不引用元数据的情况下进行调用,这导致它返回空值。解决方案是为 DropDownListFor 构建您自己的 HtmlHelper。

查看随附的 zip 文件以获取解决方法

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

日久见人心 2024-12-28 13:18:40

实际上能够通过结合我在帖子末尾提到的所有三件事来使其发挥作用。使视图模型上的属性可以为空,必需,并且必须将 ViewBage.CountryId 重命名为其他名称(我将其重命名为 CountryList)。

我通过向 ProvinceVM 添加 SelectList 属性以将其从 ViewBag 中取出来解决这个问题,然后突然 data-val* 属性显示在列表上。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文