Jquery ASP.Net MVC 3不引人注目的客户端验证不适用于下拉列表

Jquery ASP.Net MVC 3不引人注目的客户端验证不适用于下拉列表,jquery,validation,asp.net-mvc-3,drop-down-menu,unobtrusive-validation,Jquery,Validation,Asp.net Mvc 3,Drop Down Menu,Unobtrusive Validation,我有一个简单的下拉列表,列表中的第一项有一个空值。如果我没有在列表中选择任何内容,客户端验证将忽略它。我使用注释属性在模型上根据需要设置了该字段 @Html.DropDownListFor(model => Model.CCPayment.State, UnitedStatesStates.StateSelectList) [Required(ErrorMessage = "State is Required.")] public string State {

我有一个简单的下拉列表,列表中的第一项有一个空值。如果我没有在列表中选择任何内容,客户端验证将忽略它。我使用注释属性在模型上根据需要设置了该字段

 @Html.DropDownListFor(model => Model.CCPayment.State, UnitedStatesStates.StateSelectList)



[Required(ErrorMessage = "State is Required.")]
    public string State
    {
        get
        {
            return _state;
        }
        set
        {
            _state = value;
        }
    }

有什么想法吗?我遗漏了什么吗?

您提供的信息太少,我们无法查明问题所在。您可能忘记了在视图中包含适当的不引人注目的验证脚本,但谁知道呢?你还没有展示你的观点

下面是一个完整的工作示例:

型号:

public class MyViewModel
{
    [Required(ErrorMessage = "State is Required.")]
    public string State { get; set; }

    public IEnumerable<SelectListItem> States 
    { 
        get
        {
            return Enumerable.Range(1, 5).Select(x => new SelectListItem
            {
                Value = x.ToString(),
                Text = "state " + x
            });
        }
    }
}
视图:


请注意,我们是如何在DropDownListFor帮助器中提供一个默认值作为最后一个参数的。这将在开头插入一个带有空值和自定义文本的选项,如果用户没有选择某个状态,那么所需的验证器应该启动。

我在属性中添加了@class=required,就像某个家伙在codeplex的线程中所说的那样,它对我来说运行良好=

看起来像是一个合法的bug,以下是我在搜索中找到的最佳解决方法:

简而言之。将问题源DropDownListFor封装在自定义Html扩展中,然后手动检索不引人注目的客户端验证规则,如下所示:

IDictionary<string, object> validationAttributes = htmlHelper.
    GetUnobtrusiveValidationAttributes(
        ExpressionHelper.GetExpressionText(expression),
        metadata
    );

这是我发现的最简单的方法,只需在视图中DropDownListFor的HtmlAttributes中添加数据val-*-*属性。以下方法也适用于RemoteValidation,如果不需要远程验证,只需删除包含数据val remote-*的元素即可:


我希望这会有帮助。致以最良好的祝愿

如果问题是当您选择“blank”选项时,您没有看到表示该字段是必需的验证消息,那么这可能是因为Html帮助程序如何为“blank”选项生成选项标记。问题在于空值属性

<select ...>
  <option value="">
  ...
</select>
我使用这一行解决方法来删除value属性,它就像一个符咒

$'option[value=]'。删除attrvalue


所有这一切都是从任何具有空白值属性的“option”元素中删除值属性。

还要添加复选框,我有一个必需的复选框,当未选中时,该复选框不会作为错误字段亮起。这不是真正的答案,更像是一种解决方法,但是您是否尝试过使用IValidatableObject接口?目前可能会对您有所帮助?我已经在使用IValidatableObject进行服务器端验证。这是一个客户端问题。我确实在codeplex上发现了一个公开的问题,似乎问题在于属性路径的大小。如果我使用model=>model.State,它的有效性很好。但是model=>model.Address.State没有。你找到解决办法了吗?请注意,在MVC 5中,这个错误已经被修复。它应该会出现,但没有。我尝试添加默认值,但我遇到了同样的问题。我能让它工作的唯一方法是在html类属性中添加'required'。问题是,它只提供了一个通用的错误消息,而不是我在模型验证属性中指定的错误消息。对我来说,它也被破坏了。如果我排除了jq.validate.js而只包括jq.validate.unobtrusive.js,它会起作用,这很奇怪。是的,这是一个解决办法,但您会得到通用错误消息,而不是验证属性中定义的自定义错误消息。说真的,这绝对是答案!!!我花了三天的时间做这个!我永远也想不到这一点。令人惊叹的谢谢@MilimetricThis在几个小时的无所事事后救了我!!!它应该被标记为答案!谢谢尼克:这是一个非常讨厌的错误,已经发生太久了。18个月!
<select ...>
  <option value="">
  ...
</select>
public static IHtmlString DropDownListWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string label, IEnumerable<SelectListItem> items, string blankOption, object htmlAttributes = null)
{
    var l = new TagBuilder("label");
    var br = new TagBuilder("br");

    var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    var mergedAttributes = helper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata);

    if (htmlAttributes != null)
    {
        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
        {
            object value = descriptor.GetValue(htmlAttributes);
            mergedAttributes.Add(descriptor.Name, value);
        }
    }

    l.InnerHtml = label + br.ToString(TagRenderMode.SelfClosing) + helper.DropDownListFor(expression, items, blankOption, mergedAttributes);
    return MvcHtmlString.Create(l.ToString(TagRenderMode.Normal));
}
        @Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty, 
        new Dictionary<string, object>() { { "data-val", "true" }, 
        { "data-val-remote-url", "/Validation/yourremoteval" }, 
        { "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } })
<select ...>
  <option value="">
  ...
</select>