如何验证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; } }
额外修正说明
原代码存在两处错误需修正:
List<ValidationResults>应为List<ValidationResult>(类名拼写错误)- 验证方法最后不应硬返回
true,需返回实际的isValid结果
内容的提问来源于stack exchange,提问作者user22548444
相关产品推荐
相关产品推荐

