不引人注目的验证不会在单选按钮上触发
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">
我尝试了几个想法:
- 将模型类型设为常规
int
或 string
- 创建自定义验证属性并将其应用于模型 属性。
- 正如我上面所说,用内置版本替换自定义助手,试图找出原因。
所有这些都给我留下了相同的结果,单选按钮将在服务器端正确验证,但在客户端永远不会。目前我正在尝试在 jquery.validate.js
文件中进行调试,看起来所需的验证器函数实际上从未在任何单选按钮控件上调用过,如果这有助于缩小范围的话。如果有人知道如何进行验证,我将不胜感激。谢谢!
我的一位同事经过大量挖掘后发现了这一点。事实证明 jQuery 验证不会验证任何隐藏的输入。导致它认为输入被隐藏的条件之一是将高度和宽度都设置为零像素。我们对单选按钮和复选框应用了一些自定义样式,因此它们的高度和宽度都设置为零,因此它们被认为是隐藏的而不是有效的。
修复结果是使它们每个只有 1 个像素、高度和宽度。
我正在尝试使用随附的 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">
我尝试了几个想法:
- 将模型类型设为常规
int
或string
- 创建自定义验证属性并将其应用于模型 属性。
- 正如我上面所说,用内置版本替换自定义助手,试图找出原因。
所有这些都给我留下了相同的结果,单选按钮将在服务器端正确验证,但在客户端永远不会。目前我正在尝试在 jquery.validate.js
文件中进行调试,看起来所需的验证器函数实际上从未在任何单选按钮控件上调用过,如果这有助于缩小范围的话。如果有人知道如何进行验证,我将不胜感激。谢谢!
我的一位同事经过大量挖掘后发现了这一点。事实证明 jQuery 验证不会验证任何隐藏的输入。导致它认为输入被隐藏的条件之一是将高度和宽度都设置为零像素。我们对单选按钮和复选框应用了一些自定义样式,因此它们的高度和宽度都设置为零,因此它们被认为是隐藏的而不是有效的。
修复结果是使它们每个只有 1 个像素、高度和宽度。