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

.Net Core中如何实现基于条件判断的Range数据注解校验

结论

原生Range数据注解不支持你提到的动态判断写法,也无法实现你写的if逻辑切换注解的效果。C#中的特性(Attribute)属于编译期确定的元数据,所有传入的参数必须是编译期常量,无法在运行时根据其他字段的值动态修改特性配置。

可行实现方案

方案1:自定义校验特性(推荐,复用性强)

你可以继承ValidationAttribute自定义符合需求的动态范围校验特性,用法和原生数据注解基本一致,适合需要在多个模型中复用该规则的场景。
自定义特性代码示例:

public class RangeByTypeAttribute : ValidationAttribute
{
    private readonly double _fixedMin = 0.5;
    private readonly double _maxWhenTypeChecked = 20;
    private readonly double _maxWhenTypeUnchecked = 100;
    private readonly string _typeFieldName;

    public RangeByTypeAttribute(string typeFieldName)
    {
        _typeFieldName = typeFieldName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 获取关联的Type复选框值
        var typeProperty = validationContext.ObjectType.GetProperty(_typeFieldName);
        if (typeProperty == null || typeProperty.PropertyType != typeof(bool))
        {
            return new ValidationResult($"关联字段{_typeFieldName}不存在或不是布尔类型");
        }
        bool isTypeChecked = (bool)typeProperty.GetValue(validationContext.ObjectInstance);

        // 校验输入值格式
        if (value is not double inputValue)
        {
            return new ValidationResult("待校验字段必须为数值类型");
        }

        // 执行范围校验
        if (inputValue < _fixedMin)
        {
            return new ValidationResult($"数值不能小于{_fixedMin}");
        }
        double currentMax = isTypeChecked ? _maxWhenTypeChecked : _maxWhenTypeUnchecked;
        if (inputValue > currentMax)
        {
            ErrorMessage = isTypeChecked ? "<20" : "<100";
            return new ValidationResult(ErrorMessage);
        }

        return ValidationResult.Success;
    }
}

在模型中使用:

public class YourRequestModel
{
    // 对应你页面上的Type复选框
    public bool Type { get; set; }

    [RangeByType(nameof(Type))]
    public double TargetNum { get; set; }
}

如果需要同时支持客户端校验,额外实现IClientModelValidator接口添加客户端验证规则即可。

方案2:实现IValidatableObject接口(适合单模型用的复杂校验)

如果该规则只在当前一个模型中使用,不需要复用,可以直接让模型类实现IValidatableObject接口,直接在模型内部编写校验逻辑,不需要单独定义特性类:

public class YourRequestModel : IValidatableObject
{
    public bool Type { get; set; }
    public double TargetNum { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (TargetNum < 0.5)
        {
            yield return new ValidationResult("数值不能小于0.5", new[] { nameof(TargetNum) });
        }

        double max = Type ? 20 : 100;
        if (TargetNum > max)
        {
            string errorMsg = Type ? "<20" : "<100";
            yield return new ValidationResult(errorMsg, new[] { nameof(TargetNum) });
        }
    }
}

内容的提问来源于stack exchange,提问作者Micky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:24:02