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

MVC DataAnnotation RequiredIf非1值验证失效问题求助

解决RequiredIf反向条件验证不生效的问题

当前代码中,RequiredIf属性仅支持相等匹配,当使用"!1"作为目标值时,无法正确识别反向条件——因为dependentValue(比如"2")和字符串"!1"直接调用Equals必然不相等,导致CustomerCode的必填验证永远不会触发。

解决方案

修改RequiredIfAttribute的逻辑,使其支持以!开头的反向条件判断,具体代码调整如下:

public class RequiredIfAttribute : ValidationAttribute
{
    private readonly RequiredAttribute _innerAttribute = new RequiredAttribute();
    public string DependentProperty { get; set; }
    public object TargetValue { get; set; }
    private bool _isReverseCondition;
    private object _actualTargetValue;

    public RequiredIfAttribute(string dependentProperty, object targetValue)
    {
        DependentProperty = dependentProperty;
        TargetValue = targetValue;

        // 解析反向条件:识别以!开头的目标值
        if (targetValue is string targetStr && targetStr.StartsWith("!"))
        {
            _isReverseCondition = true;
            _actualTargetValue = targetStr.Substring(1);
        }
        else
        {
            _isReverseCondition = false;
            _actualTargetValue = targetValue;
        }
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var field = validationContext.ObjectType.GetProperty(DependentProperty);
        if (field == null)
        {
            return new ValidationResult(FormatErrorMessage(DependentProperty));
        }

        var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
        bool conditionMet = false;

        // 处理null值匹配逻辑
        if (dependentValue == null && _actualTargetValue == null)
        {
            conditionMet = !_isReverseCondition;
        }
        else
        {
            // 统一转为字符串比较,适配当前ViewModel的string类型属性,可扩展支持其他类型
            string dependentStr = dependentValue?.ToString();
            string targetStr = _actualTargetValue?.ToString();
            
            if (_isReverseCondition)
            {
                // 反向条件:依赖值不等于目标值时触发验证
                conditionMet = !string.Equals(dependentStr, targetStr, StringComparison.OrdinalIgnoreCase);
            }
            else
            {
                // 正向条件:依赖值等于目标值时触发验证
                conditionMet = string.Equals(dependentStr, targetStr, StringComparison.OrdinalIgnoreCase);
            }
        }

        if (conditionMet)
        {
            if (!_innerAttribute.IsValid(value))
            {
                string name = validationContext.DisplayName;
                string specificErrorMessage = ErrorMessage ?? $"{name} is required.";
                return new ValidationResult(specificErrorMessage, new[] { validationContext.MemberName });
            }
        }

        return ValidationResult.Success;
    }
}

修改说明

  • 新增反向条件解析逻辑:自动识别以!开头的目标值,拆分出实际需要匹配的内容
  • 统一字符串比较:避免不同类型导致的匹配错误,同时加入忽略大小写的选项(可按需调整)
  • 优化条件判断:反向条件下检查依赖值不等于目标值,正向条件下检查等于,完全符合业务需求
  • 完善null值处理:覆盖依赖属性或目标值为null的边界情况

验证效果

保持原ViewModel代码不变:

public class FilteringViewModel
{
    [Required]
    public int? UserID { get; set; }

    [Required]
    public string UserTypeID { get; set; }

    [RequiredIf("UserTypeID", "1")]
    public string EmployeeCode { get; set; }

    [RequiredIf("UserTypeID", "!1")]
    public string CustomerCode { get; set; }
}

修改后验证逻辑正常工作:

  • UserTypeID为1时,EmployeeCode必填验证正常触发
  • UserTypeID不为1(如2、3等)时,CustomerCode必填验证正确生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:36:16