MVC中如何为动态复选框实现至少选一个的自定义验证
实现动态复选框的「至少选一个」验证(服务器端+客户端)
问题背景
现有从SQL数据库获取的动态复选框列表,模型和视图代码如下:
模型代码
public class TestModel { public List<CheckboxList_model> DynamicCheckbox { get; set; } } public class CheckboxList_model { public string Text { get; set; } public int Value { get; set; } public Boolean Selected { get; set; } }
视图代码
@for (int i = 0; i < Model.DynamicCheckbox.Count(); i++) { @Html.CheckBoxFor(m => m.DynamicCheckbox[i].Selected, new { @class = "flat" }) @Html.DisplayFor(m => m.DynamicCheckbox[i].Text) @Html.HiddenFor(m => m.DynamicCheckbox[i].Value) } @Html.ValidationMessageFor(model => model.DynamicCheckbox, "", new { @class = "text-danger" })
需要实现服务器端+客户端双重验证,确保用户至少选中一个复选框。
一、服务器端验证
方法1:自定义验证属性(推荐)
创建针对List<CheckboxList_model>的自定义验证属性,检查是否存在至少一个Selected为true的项:
using System.ComponentModel.DataAnnotations; public class AtLeastOneSelectedAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var checkboxList = value as List<CheckboxList_model>; if (checkboxList != null && !checkboxList.Any(item => item.Selected)) { return new ValidationResult(ErrorMessage ?? "请至少选择一个选项"); } return ValidationResult.Success; } }
在TestModel的DynamicCheckbox属性上标记该属性:
public class TestModel { [AtLeastOneSelected(ErrorMessage = "请至少选择一个选项")] public List<CheckboxList_model> DynamicCheckbox { get; set; } }
控制器Post方法中通过ModelState.IsValid判断验证结果:
[HttpPost] public ActionResult YourAction(TestModel model) { if (ModelState.IsValid) { // 验证通过,执行业务逻辑 return RedirectToAction("Success"); } // 验证失败,返回原视图 return View(model); }
方法2:控制器内手动验证(快速实现)
若不想创建自定义属性,可直接在Post方法中检查:
[HttpPost] public ActionResult YourAction(TestModel model) { if (!model.DynamicCheckbox.Any(item => item.Selected)) { ModelState.AddModelError("DynamicCheckbox", "请至少选择一个选项"); } if (ModelState.IsValid) { // 执行业务逻辑 return RedirectToAction("Success"); } return View(model); }
二、客户端验证
要实现客户端即时验证,需扩展jQuery Validate规则,并让自定义验证属性支持客户端验证。
步骤1:让自定义属性实现客户端验证接口
修改AtLeastOneSelectedAttribute,实现IClientValidatable接口:
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Web.Mvc; public class AtLeastOneSelectedAttribute : ValidationAttribute, IClientValidatable { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var checkboxList = value as List<CheckboxList_model>; if (checkboxList != null && !checkboxList.Any(item => item.Selected)) { return new ValidationResult(ErrorMessage ?? "请至少选择一个选项"); } return ValidationResult.Success; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule { ValidationType = "atleastoneselected", ErrorMessage = ErrorMessage ?? "请至少选择一个选项" }; yield return rule; } }
步骤2:添加客户端验证脚本
在视图底部(或布局页)添加自定义验证脚本:
<script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <script> // 注册自定义验证方法 $.validator.addMethod("atleastoneselected", function (value, element, params) { // 匹配所有动态复选框的Selected控件 var checkboxes = $('input[name^="DynamicCheckbox["][name$="].Selected"]'); return checkboxes.is(':checked'); }); // 注册验证适配器,关联服务器端规则 $.validator.unobtrusive.adapters.add("atleastoneselected", [], function (options) { options.rules["atleastoneselected"] = true; options.messages["atleastoneselected"] = options.message; }); </script>
这样用户提交表单前,客户端会自动检查复选框选中状态,未选中时即时显示错误提示,无需回发服务器。
内容的提问来源于stack exchange,提问作者Dev Net
相关产品推荐
相关产品推荐

