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

.NET Core中如何实现通用自定义验证类(属性1为真时属性2必填)

嘿,我来帮你把这个验证类改成通用版本,这样你就能在任何需要「当某个布尔属性为true时,另一个属性必须填写」的场景下复用它了!

第一步:改造通用验证属性类

咱们把原来的RequiredIfLocalArrangements改个更通用的名字,比如RequiredIfTrueAttribute,然后让它支持传入依赖的布尔属性名称,这样就能灵活适配不同的属性组合了。代码如下:

using System;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace MyProject.Validation
{
    public class RequiredIfTrueAttribute : ValidationAttribute
    {
        private readonly string _dependentPropertyName;

        // 构造函数:传入需要依赖的布尔属性名称,必填
        public RequiredIfTrueAttribute(string dependentPropertyName)
        {
            _dependentPropertyName = dependentPropertyName ?? throw new ArgumentNullException(nameof(dependentPropertyName));
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            // 获取当前验证的模型对象
            var model = validationContext.ObjectInstance;
            if (model == null)
                return ValidationResult.Success;

            // 通过反射找到依赖的属性
            var dependentProperty = model.GetType().GetProperty(_dependentPropertyName);
            if (dependentProperty == null)
                return new ValidationResult($"找不到指定的依赖属性: {_dependentPropertyName}");

            // 确保依赖属性是布尔类型,避免传入错误的属性
            if (dependentProperty.PropertyType != typeof(bool))
                return new ValidationResult($"依赖属性 {_dependentPropertyName} 必须是bool类型");

            // 获取依赖属性的当前值
            bool isDependentPropertyTrue = (bool)dependentProperty.GetValue(model);

            // 如果依赖属性为true,就检查当前属性是否为空/空白
            if (isDependentPropertyTrue)
            {
                bool isCurrentValueEmpty = value == null 
                    || (value is string strValue && string.IsNullOrWhiteSpace(strValue));

                if (isCurrentValueEmpty)
                {
                    // 优先用自定义错误消息,没有的话用默认提示
                    string errorMsg = string.IsNullOrEmpty(ErrorMessage)
                        ? $"当 {_dependentPropertyName} 为true时,此字段为必填项"
                        : ErrorMessage;
                    return new ValidationResult(errorMsg);
                }
            }

            // 所有验证条件都满足,返回成功
            return ValidationResult.Success;
        }
    }
}

第二步:在视图模型中复用这个通用验证

现在你可以在任何需要的属性上使用这个验证,只需要指定依赖的布尔属性名称就行,甚至可以自定义错误消息:

using System.ComponentModel.DataAnnotations;
using MyProject.Validation;

namespace MyProject.ViewModels
{
    public class YourViewModel
    {
        public bool IsLocalArrangement { get; set; }

        // 用nameof()获取属性名,避免硬编码字符串,重构更安全
        [RequiredIfTrue(nameof(IsLocalArrangement), ErrorMessage = "选择本地安排时,必须填写详细信息")]
        public string LocalArrangementDetail { get; set; }

        // 还能在其他场景复用,比如发票需求
        public bool IsNeedInvoice { get; set; }

        [RequiredIfTrue(nameof(IsNeedInvoice), ErrorMessage = "需要发票时,请填写发票抬头")]
        public string InvoiceTitle { get; set; }
    }
}

几个小细节说明

  • 用nameof()代替硬编码的属性字符串,这样后续重构属性名时不会出错
  • 这个验证类不仅支持string类型,对于可空值类型(比如int?、DateTime?)也能生效——只要依赖属性为true,当前属性为null就会触发验证
  • 代码里加了对依赖属性的合法性检查,比如确保它存在、是bool类型,能帮你提前发现错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:41:27