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

如何验证C#类中带有Required特性的私有属性?

验证C#私有属性的DataAnnotations特性

.NET的DataAnnotations Validator默认仅扫描公共属性/字段,私有成员不会被自动纳入验证范围,所以你加在私有SomeId上的[Required]特性无法触发验证。以下是两种可行的解决方法:

方案一:手动反射遍历私有属性并验证

通过反射获取目标对象的所有属性(包括私有),逐个检查其DataAnnotations特性并执行验证。

修改你的ValidatePOCO.IsValid方法如下:

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

public static class ValidatePOCO
{
    public static bool IsValid(object myPoco)
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new ValidationContext(myPoco);
        
        // 验证公共属性(保留原有逻辑)
        bool isValid = Validator.TryValidateObject(myPoco, validationContext, validationResults, validateAllProperties: true);

        // 手动获取所有私有实例属性
        var privateProps = myPoco.GetType()
            .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic);

        foreach (var prop in privateProps)
        {
            // 获取属性上的所有验证特性
            var attributes = prop.GetCustomAttributes<ValidationAttribute>(inherit: false);
            var propValue = prop.GetValue(myPoco);

            foreach (var attr in attributes)
            {
                if (!attr.IsValid(propValue))
                {
                    isValid = false;
                    validationResults.Add(new ValidationResult(
                        attr.FormatErrorMessage(prop.Name),
                        new[] { prop.Name }));
                }
            }
        }

        return isValid;
    }
}

方案二:自定义ValidationContext包含私有属性

通过继承ValidationContext,重写GetProperties方法,让它返回所有属性(包括私有),这样Validator.TryValidateObject就能自动扫描私有成员。

首先定义自定义ValidationContext:

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

public class PrivatePropertyValidationContext : ValidationContext
{
    public PrivatePropertyValidationContext(object instance) : base(instance)
    {
    }

    protected override IEnumerable<PropertyDescriptor> GetProperties()
    {
        // 获取所有实例属性(公共+私有)并转换为PropertyDescriptor
        var props = Instance.GetType()
            .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
            .Select(p => TypeDescriptor.GetProperties(Instance.GetType())[p.Name]);

        return props;
    }
}

然后修改验证方法:

public static class ValidatePOCO
{
    public static bool IsValid(object myPoco)
    {
        var validationResults = new List<ValidationResult>();
        var validationContext = new PrivatePropertyValidationContext(myPoco);
        
        bool isValid = Validator.TryValidateObject(myPoco, validationContext, validationResults, validateAllProperties: true);

        return isValid;
    }
}

额外修正说明

原代码存在两处错误需修正:

  1. List<ValidationResults>应为List<ValidationResult>(类名拼写错误)
  2. 验证方法最后不应硬返回true,需返回实际的isValid结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:40:10