ASP.NET Core 3.1多自定义验证属性:客户端data-val仅加载首个属性问题
解决方案:单一复合验证属性 + 自定义客户端验证逻辑
别用两个独立的AgeRange属性了,换成一个能处理多区间的自定义验证属性,同时配合客户端自定义验证逻辑,就能解决多规则触发不同模态框的问题。
1. 创建复合年龄验证属性
这个属性会同时处理所有年龄区间规则,并在客户端输出自定义验证标记:
public class AgeRangeValidationAttribute : ValidationAttribute, IClientModelValidator { public void AddValidation(ClientModelValidationContext context) { // 添加自定义验证标识 context.Attributes.Add("data-val-age-range", "年龄验证未通过"); // 传递区间参数,用逗号分隔各区间 context.Attributes.Add("data-val-age-range-ranges", "0-63,64-79"); } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value is DateTime dateOfBirth) { var today = DateTime.Today; var age = today.Year - dateOfBirth.Year; // 修正未到生日的情况 if (dateOfBirth.Date > today.AddYears(-age)) age--; if (age < 64) { return new ValidationResult("Under64"); } else if (age >= 65 && age <= 80) { return new ValidationResult("Between65And80"); } else if (age > 80) { return ValidationResult.Success; } } return new ValidationResult("无效的出生日期"); } }
在模型上应用这个属性:
public class UserModel { [AgeRangeValidation] public DateTime DateOfBirth { get; set; } }
2. 自定义客户端jQuery Unobtrusive验证适配器
在页面的JS代码中添加自定义验证逻辑,解析我们的自定义属性,计算年龄后触发对应模态框:
// 注册自定义验证适配器 $.validator.unobtrusive.adapters.add( 'age-range', ['ranges'], function (options) { options.rules['agerange'] = { ranges: options.params.ranges.split(',').map(range => { const [min, max] = range.split('-').map(Number); return { min, max }; }) }; options.messages['agerange'] = options.message; } ); // 添加自定义验证方法 $.validator.addMethod('agerange', function (value, element, params) { if (!value) return true; // 空值可单独添加[Required]验证 const dob = new Date(value); const today = new Date(); let age = today.getFullYear() - dob.getFullYear(); const monthDiff = today.getMonth() - dob.getMonth(); // 修正未到生日的年龄计算 if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dob.getDate())) { age--; } // 根据年龄触发对应模态框 if (age < 64) { $('#ModalA').modal('show'); return false; // 标记验证不通过 } else if (age >= 65 && age <= 80) { $('#ModalB').modal('show'); return false; } else if (age > 80) { return true; // 验证通过 } return false; });
3. 额外说明
- 服务器端返回的
ValidationResult可以用于后端逻辑处理,比如表单提交后后端验证不通过,可根据返回的错误标识在页面加载时触发对应模态框。 - 确保页面已引入
jquery.validate.js和jquery.validate.unobtrusive.js,这是ASP.NET Core客户端验证的基础依赖。 - 如果一定要保留多属性的服务器端验证,也可以修改
IClientModelValidator的实现,在AddValidation时追加不同的自定义data属性(比如data-val-age-under64、data-val-age-between65-80),再对应编写多个客户端验证方法,但这种方式不如单一复合属性简洁。
内容的提问来源于stack exchange,提问作者smashraid
相关产品推荐
相关产品推荐

