You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:41:02