多个复选框的自定义DataAnnotation

好吧,所以我有这些产品的复选框,我想确保至少选择了一个产品。

为此,我的ViewModel包含:

[DisplayName(@"Product Line")] [MinChecked(1)] public List 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 valueList = (List)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 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; }); 

因此,validation工作在服务器端。

但是,如何让不引人注目的validation工作? 出于某种原因,

GetClientValidationRules未将HTML5附加到复选框。

我有一个非常类似于上面的实现,这个客户端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中,用于生成一个复选框列表。 服务器端将无法工作,但客户端validation确实可以使用此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 }); });