不引人注目的验证不会在单选按钮上触发

Unobtrusive validation doesn't fire on radio buttons

我正在尝试使用随附的 jQuery.Validate 在 JavaScript 中获取要验证的表单。文本和 select 输入在 JavaScript 中正确验证,但我在表单中包含的任何单选按钮组仅在服务器上验证。我怎样才能让客户端验证工作?我的观点片段如下:

@Html.AccessibleValidationMessageFor(m => m.DeliveryMethod)
@foreach (var deliveryMethod in Model.GetDeliveryMethodsOrdered())
{
    @Html.AccessibleRadioButtonFor(m => m.DeliveryMethod, deliveryMethod.Id, new { id = string.Format("DeliveryMethod_{0}", deliveryMethod.Id) })
    <label for="DeliveryMethod_@deliveryMethod.Id">@deliveryMethod.Description</label>
}

我正在使用内置 HTML 助手的一些扩展,但我不认为这是导致问题的原因,因为我也尝试过内置 @Html.RadioButtonFor@Html.ValidationMessageFor帮手。以防万一,这是自定义帮助程序代码。

    public static IHtmlString AccessibleRadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, object values, object htmlAttributes = null)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);



        var fieldName = ExpressionHelper.GetExpressionText(expression);
        var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
        var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
        if (!html.ViewData.ModelState.IsValidField(fullBindingName))
        {
            if (!validationAttributes.ContainsKey("aria-describedby"))
            {
                validationAttributes.Add("aria-describedby", fullBindingName.ToLower() + "-valMsg");
                validationAttributes.Add("aria-invalid", "true");
            }
        }

        RouteValueDictionary routeValues = new RouteValueDictionary(htmlAttributes);
        if (routeValues != null)
        {
            foreach (var attribute in validationAttributes)
            {
                routeValues.Add(attribute.Key, attribute.Value);
            }
            return html.RadioButtonFor(expression, values, routeValues);
        }
        return html.RadioButtonFor(expression, values, validationAttributes);
    }

在模型中,我使类型可为空并添加了必需的属性。

    [Required]
    [Display(Name = "Delivery Method")]
    public int? DeliveryMethod { get; set; }

通过此设置,单选按钮呈现为:

<input aria-describedby="deliverymethod-valMsg" aria-invalid="true" 
    class="input-validation-error" data-val="true" data-val-number="The field Delivery Method must be a number." 
    data-val-required="The Delivery Method field is required." id="DeliveryMethod_-1" 
    name="DeliveryMethod" type="radio" value="-1">

我尝试了几个想法:

所有这些都给我留下了相同的结果,单选按钮将在服务器端正确验证,但在客户端永远不会。目前我正在尝试在 jquery.validate.js 文件中进行调试,看起来所需的验证器函数实际上从未在任何单选按钮控件上调用过,如果这有助于缩小范围的话。如果有人知道如何进行验证,我将不胜感激。谢谢!

我的一位同事经过大量挖掘后发现了这一点。事实证明 jQuery 验证不会验证任何隐藏的输入。导致它认为输入被隐藏的条件之一是将高度和宽度都设置为零像素。我们对单选按钮和复选框应用了一些自定义样式,因此它们的高度和宽度都设置为零,因此它们被认为是隐藏的而不是有效的。

修复结果是使它们每个只有 1 个像素、高度和宽度。