MVC 3中不显眼的下拉确认

时间:2011-05-24 20:54:38

标签: asp.net-mvc asp.net-mvc-3

因此下面的链接概述了使用下拉列表进行MVC 3 /不显眼验证的问题。下拉列表不会发出基本上客户端验证脚本。有一个简单的解决方法吗?我很困惑MVC 3是如何在最终版本之前报告这个错误的时候发布的。在我们等待修复时,是否有一个简单的解决方案?

也许我对此并不孤单,但似乎验证表格的所有元素都很重要。 :)

DropDownListFor() Unobtrusive Validation Problem

4 个答案:

答案 0 :(得分:4)

我意识到这个问题已经得到了回答,但是我在过去一天试图弄清楚为什么上面的例子工作得很好但是我的代码没有处理这个问题的墙上打了我的脑袋。

事实证明,如果您尝试使用与正在设置的属性相同的名称将选择列表放入ViewData或ViewBag,则客户端验证将不起作用。但是,下拉列表将填充,因此它非常不直观。

// Do NOT do this:
// In the controller:
ViewBag.ItemID = Database.Items.Select(i => new SelectListItem(){Value = i.ID, Text = i.Name});
// In the view:
@Html.DropDownList("ItemID")

// Instead DO this
// In the controller:
ViewBag.ItemIDList = Database.Items.Select(i => new SelectListItem(){Value = i.ID, Text = i.Name});
// In the view:    
@Html.DropDownListFor(m => m.ItemID, (IEnumerable<SelectListItem>)ViewBag.ItemIDList)

虽然前者产生了一个功能完善的下拉菜单,但它却不能得到客户端验证。如果检查HTML,那么'select'元素上的所有属性都不存在。

这与MVC中每个其他字段或编辑器的填充方式完全相反,因为您可以通过设置ViewBag.ItemName =“Bob”来设置默认值和当前值,如果您有一个“ItemName”文本框,它将填充“鲍勃”。

希望我发布此信息可以为同一个人节省长达数小时的时间。

答案 1 :(得分:2)

您可以将所需的data- *属性附加到元素,以便通过不显眼的验证脚本获取它们。

@Html.DropDownListFor(x => x.People, new SelectList(Model.People,"Id", "Name"), "Select Person", new Dictionary<string, object>() {{ "data-val", "true" }, { "data-val-required", "Please select a person" }} )

答案 2 :(得分:1)

它似乎也适合我

   <p>                                                         
       <p>
            <span class="lbl"> @Html.LabelFor(x => x.SelectedTimeZone, " Select a TimeZone: ")</span>
            <span>@Html.DropDownListFor(x => x.SelectedTimeZone, Model.TimeZones)</span>
            <span class="validation-error">@Html.ValidationMessageFor(x => x.SelectedTimeZone)</span>    
        </p>

//查看模型

  [Required(ErrorMessage = "Time zone is required")]
    public string SelectedTimeZone { get; set; }
    public SelectList TimeZones { get; set; }

    public SetupViewModel()
    {
        TimeZones = new SelectList(TimeZoneExtensions.BuildTimeZoneList(), "value", "text", "selected");
        SelectedTimeZone = "UTC";
    }

答案 3 :(得分:0)

啊,这很奇怪,以下对我来说完全没问题。

查看型号:

public class MyViewModel
{
    [Required]
    public string SelectedItem { get; set; }

    public IEnumerable<SelectListItem> Items
    {
        get
        {
            return Enumerable.Range(1, 5).Select(x => new SelectListItem
            {
                Value = x.ToString(),
                Text = "item " + x
            });
        }
    }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

查看:

@using AppName.Models
@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())
{
    @Html.DropDownListFor(
        x => x.SelectedItem,
        new SelectList(Model.Items, "Value", "Text"),
        "-- please select an item --"
    )
    @Html.ValidationMessageFor(x => x.SelectedItem)
    <input type="submit" value="OK" />
}

在不选择值的情况下保留下拉列表,客户端验证将立即触发。