C# Excel导出场景下如何用Data Annotation验证部门与子部门不重复
实现Product模型的跨字段验证
针对你需要验证Department和SubDepartment不能相同的需求,这里提供两种可行的实现方案:
方案一:自定义Data Annotation特性
如果后续多个模型都需要类似的“两个字段值不能相同”的验证,推荐用这种可复用的自定义特性:
首先创建自定义验证特性:
public class DifferentValuesAttribute : ValidationAttribute { private readonly string _targetPropertyName; public DifferentValuesAttribute(string targetPropertyName) { _targetPropertyName = targetPropertyName; ErrorMessage = "{0} 与 {1} 的值不能重复"; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var targetProperty = validationContext.ObjectType.GetProperty(_targetPropertyName); if (targetProperty == null) { return new ValidationResult($"未找到指定属性:{_targetPropertyName}"); } var targetValue = targetProperty.GetValue(validationContext.ObjectInstance); // 此处逻辑:若两个值(含null)相等则触发验证错误,可根据实际需求调整 if (Equals(value, targetValue)) { return new ValidationResult(string.Format(ErrorMessage, validationContext.DisplayName, _targetPropertyName)); } return ValidationResult.Success; } }
然后在Product模型中应用该特性:
public class Product { public int Id { get; set; } [Required] [StringLength(10)] public string Name { get; set; } [DifferentValues(nameof(SubDepartment))] public string Department { get; set; } public string SubDepartment { get; set; } }
验证时使用Validator类执行检查:
var product = new Product { Department = "IT", SubDepartment = "IT" }; var validationResults = new List<ValidationResult>(); var isValid = Validator.TryValidateObject(product, new ValidationContext(product), validationResults, validateAllProperties: true); if (!isValid) { foreach (var result in validationResults) { // 输出或处理验证错误信息 Console.WriteLine(result.ErrorMessage); } }
方案二:实现IValidatableObject接口
如果只是当前Product模型需要这个验证逻辑,直接实现接口更简单,不需要额外创建特性类:
修改后的Product模型:
using System.ComponentModel.DataAnnotations; using System.Collections.Generic; public class Product : IValidatableObject { public int Id { get; set; } [Required] [StringLength(10)] public string Name { get; set; } public string Department { get; set; } public string SubDepartment { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Equals(Department, SubDepartment)) { yield return new ValidationResult( "部门与子部门的值不能相同", new[] { nameof(Department), nameof(SubDepartment) }); } } }
验证方式和方案一一致,通过Validator.TryValidateObject即可获取验证结果。
两种方案对比
- 自定义Data Annotation:复用性强,适合多个模型共享相同验证规则的场景
- IValidatableObject:实现成本低,适合单个模型的专属验证逻辑
内容的提问来源于stack exchange,提问作者Vidya R
相关产品推荐
相关产品推荐

