我有这个自定义验证代码,用于检查是否选中了两个复选框,但只显示了两个复选框。
public class SeveralCheckboxesRequiredAttribute : ValidationAttribute, IClientValidatable
{
private readonly string[] _properties;
public SeveralCheckboxesRequiredAttribute(params string[] properties)
{
ErrorMessage = "You must confirm you have entered the correct information ";
ErrorMessage += "for your income and expenditure. Wrong information may result in ";
ErrorMessage += "us not being able to lend to you at this time or in the future.";
_properties = properties;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (_properties == null || _properties.Length < 1)
{
return null;
}
foreach (var prop in _properties)
{
var property = validationContext.ObjectType.GetProperty(prop);
var propertyValue = (bool)property.GetValue(validationContext.ObjectInstance, null);
if (!propertyValue)
{
// At least one property is false => the model is not valid
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessage,
ValidationType = "severalcheckboxesrequired"
};
rule.ValidationParameters["properties"] = string.Join(",", _properties);
yield return rule;
}
}
客户端是:
jQuery.validator.addMethod('severalcheckboxesrequired', function (value, element, params) {
var props = params.properties.split(','),
isValid = true;
for (var i = 0; i < props.length; i++) {
var property = props[i];
if (!$('#' + property).is(':checked')) {
isValid = false;
break;
}
}
return isValid;
}, '');
jQuery.validator.unobtrusive.adapters.add(
'severalcheckboxesrequired',
['properties'],
function (options) {
options.rules['severalcheckboxesrequired'] = options.params;
options.messages['severalcheckboxesrequired'] = options.message;
}
);
与此相关的模型属性为:
[SeveralCheckboxesRequired("AccurateInformation", "FutureInformation")]
[Display(Name = "Please tick here to confirm you have provided accurate information.")]
public bool AccurateInformation { get; set; }
[Display(Name = "Please tick here to confirm that you have considered potential future information.")]
public bool FutureInformation { get; set; }
视图包含此
<div class="grid_12">
<div class="checkboxWrapper">
@Html.LabelFor(m => m.AccurateInformation)
@Html.CheckBoxFor(m => m.AccurateInformation)
@Html.LabelFor(m => m.FutureInformation)
@Html.CheckBoxFor(m => m.FutureInformation)
</div>
</div>
<div class="grid_12">
@Html.ValidationMessageFor(m => m.AccurateInformation)
</div>
我的目标是在没有检查当前不起作用时突出显示它们。但这是现在的一个小问题。主要的问题是,为了实现这一点,我只是装饰其中一个,好像我在类级别使用属性我无法进行客户端验证。
这种情况在这种情况下导致和问题:你提交的表单只有第一个(装饰的)检查而不是第二个,你得到客户端错误(虽然没有突出显示,但是你得到了消息)。然后你检查第二个,验证器方法显然不是触发器,你必须实际点击提交按钮使消息消失。有没有办法将第二个绑定到同一个验证器方法?有更好的解决方案吗?甚至可以突出显示这个被忽视的复选框?
由于
更新:在这个问题的第二个阶段,我提出了一个远非理想的解决方法,但万一有人遇到同样的问题并且没有更好的...
我添加了这个类&#39;分享&#39;到两个复选框(注意我必须使用Html.CheckBoxFor而不是EditorFor才能添加类)
<div class="grid_12">
<div class="checkboxWrapper">
@Html.LabelFor(m => m.AccurateInformation)
@Html.CheckBoxFor(m => m.AccurateInformation, new {@class='shared'})
@Html.LabelFor(m => m.FutureInformation, new {@class='shared'})
@Html.CheckBoxFor(m => m.FutureInformation)
</div>
</div>
<div class="grid_12">
这段代码在js文件中
$(document).ready(function(){
$('.shared').on('change', function () {
$('.shared[data-val-severalcheckboxesrequired]').valid();
});
});
每当任何依赖项(或其自身)发生更改时,这基本上会触发对带注释的复选框的验证,因为自定义验证程序检查每次发生此触发器时都会检查所有它们,所有这些都必须进行检查才能生成消息消失了。