使用TryValidateProperty验证嵌套Address属性时报错的解决方法
解决嵌套类属性验证失败的问题
错误原因
你遇到的ArgumentException是因为TryValidateProperty的MemberName参数必须对应当前验证上下文实例的属性名。你用Customer实例作为验证上下文,却指定MemberName = "Address.City",但Customer类根本没有这个属性(你的属性名实际是Addresse,还多了个字母e),自然会报错。
正确验证方式
步骤1:确保Address类带有验证特性
先给Address的属性加上对应的验证标签,示例如下:
public class Address { [Required(ErrorMessage = "{0} is mandatory")] public string City { get; set; } // 其他属性的验证标签按需添加 public string Street { get; set; } }
步骤2:修改Customer的Validate方法
验证嵌套属性时,需要切换验证上下文到嵌套对象本身,再将错误信息的成员名称映射为父对象的嵌套路径,具体代码如下:
public class Customer { [Required(ErrorMessage = "{0} is mandatory")] [MaxLength(50, ErrorMessage = "The {0} can not have more than {1} characters")] public string Name { get; set; } [Required(ErrorMessage = "{0} is mandatory")] [Range(0, 150, ErrorMessage = "The Age should be between 0 and 150 years")] public int Age { get; set; } [Required(ErrorMessage = "{0} is mandatory")] // 建议把属性名改成Address(去掉多余的e),更符合命名规范 public Address? Addresse { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { var results = new List<ValidationResult>(); // 验证Customer自身的Name属性 Validator.TryValidateProperty(this.Name, new ValidationContext(this) { MemberName = nameof(Name) }, results); // 验证Customer自身的Age属性 Validator.TryValidateProperty(this.Age, new ValidationContext(this) { MemberName = nameof(Age) }, results); // 验证Addresse属性本身的Required特性 Validator.TryValidateProperty(this.Addresse, new ValidationContext(this) { MemberName = nameof(Addresse) }, results); // 如果Addresse不为null,验证其内部属性 if (this.Addresse != null) { var addressValidationResults = new List<ValidationResult>(); // 验证整个Address实例的所有属性(validateAllProperties设为true) Validator.TryValidateObject( this.Addresse, new ValidationContext(this.Addresse), addressValidationResults, validateAllProperties: true); // 将Address的错误成员名称映射为嵌套路径(比如Addresse.City) foreach (var addrResult in addressValidationResults) { var nestedMemberNames = addrResult.MemberNames .Select(mn => $"{nameof(Addresse)}.{mn}"); results.Add(new ValidationResult(addrResult.ErrorMessage, nestedMemberNames)); } } return results; } }
可选优化:修正属性名拼写
你的Customer类里属性名是Addresse(多了个e),建议改成Address以符合命名规范,同时代码里的nameof(Addresse)也要同步改成nameof(Address)。
验证效果
运行验证代码后,会得到正确的错误信息(比如Addresse.City is mandatory),且不会再抛出ArgumentException。
内容的提问来源于stack exchange,提问作者Aabir
相关产品推荐
相关产品推荐

