不打扰的验证不会在单选按钮上触发

时间:2019-05-22 18:45:49

标签: c# jquery asp.net-mvc unobtrusive-validation

我正在尝试使用随附的jQuery.Validate获取一个表单以在JavaScript中进行验证。文本和选择输入在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">

我尝试了几种方法:

  • 将模型类型设置为常规intstring
  • 创建自定义验证属性并将其应用于模型属性。
  • 正如我上面所说,用内置版本替换自定义帮助程序,试图找出原因。

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

1 个答案:

答案 0 :(得分:0)

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

原来的解决方法是使它们每个只有1个像素(高度和宽度)。