好吧,所以我有这些产品的复选框,我想确保至少选择了一个产品。
为此,我的ViewModel包含:
[DisplayName(@"Product Line")]
[MinChecked(1)]
public List<CheckboxInfo> ActiveProducts { get; set; }
视图只包含:
@Html.EditorFor(x => x.ActiveProducts)
EditorTemplate包含:
@model Rad.Models.CheckboxInfo
@Html.HiddenFor(x => x.Value)
@Html.HiddenFor(x => x.Name)
@Html.CheckBoxFor(x => x.Selected)
@Html.LabelFor(x => x.Selected, Model.Name)
自定义数据注释是:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class MinCheckedAttribute : ValidationAttribute, IClientValidatable
{
public int MinValue { get; set; }
public MinCheckedAttribute(int minValue)
{
MinValue = minValue;
ErrorMessage = "At least " + MinValue + " {0} needs to be checked.";
}
public override string FormatErrorMessage(string propName)
{
return string.Format(ErrorMessage, propName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
try
{
List<CheckboxInfo> valueList = (List<CheckboxInfo>)value;
foreach (var valueItem in valueList)
{
if (valueItem.Selected)
{
return ValidationResult.Success;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
catch (Exception x)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "minchecked",
};
rule.ValidationParameters["minvalue"] = MinValue;
yield return rule;
}
}
jQuery部分是:
$.validator.addMethod('minchecked', function (value, element, params) {
var minValue = params['minvalue'];
alert(minValue);
$(element).each(function () {
if ($(this).is(':checked')) {
return true;
}
});
return false;
});
$.validator.unobtrusive.adapters.add('minchecked', ['minvalue'], function (options) {
options.messages['minchecked'] = options.message;
options.rules['minchecked'] = options.params;
});
因此,验证工作在服务器端。
但是,如何让不引人注目的验证工作?出于某种原因,
GetClientValidationRules
未将HTML5附加到复选框。
答案 0 :(得分:1)
我有一个非常类似于上面的实现,这个客户端jquery代码可以为一组作为模型一部分的复选框工作(附加到HTML5)。它将从数据注释中传输ErrorMessage。
[Display(Name = "Location1")]
[CheckAtLeastOne(ErrorMessage = "Must check at least one Location")]
public DateTime Location1 { get; set; }
[Display(Name = "Location2")]
public DateTime Location2 { get; set; }
[Display(Name = "Location3")]
public DateTime Location3 { get; set; }
[Display(Name = "Location4")]
public DateTime Location4 { get; set; }
$(function () {
$.validator.addMethod("checkatleastone", function (value, element) {
var tag = $("#editform-locations").find(":checkbox");
return tag.filter(':checked').length;
});
});
$.validator.unobtrusive.adapters.addBool("checkatleastone");
但是,在我的情况下,我有另一个不属于模型的复选框。它是一个单独的表,因此它被填充在一个Viewbag中,用于生成一个复选框列表。服务器端不起作用,但客户端验证通过使用此jquery并将匹配的类名添加到复选框的html中来确实有效。
$(function () {
$.validator.addMethod("CheckOneCategory", function (value, element) {
var tag = $("#editform-categories").find(":checkbox");
return tag.filter(':checked').length;
}, "Select at least one Product/Service Category");
$.validator.addClassRules("require-one-category", { CheckOneCategory: true });
});