.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
相关产品推荐
相关产品推荐

