使用IValidatableObject校验更新请求是否至少设置一个有效参数
方案1:.NET 8及以上版本直接使用内置特性
.NET 8 开始在System.ComponentModel.DataAnnotations命名空间下新增了原生的[MembersRequired]特性,直接标记到请求类上即可实现「至少赋值一个属性」的校验,完全不需要自己写校验逻辑:
using System.ComponentModel.DataAnnotations; [MembersRequired(MinimumRequired = 1, ErrorMessage = "至少需要设置一个更新属性")] public class UpdateAccountRequest { public bool? Disabled { get; set; } // 后续新增任意可更新属性都会自动纳入校验,无需修改代码 }
只要请求体所有属性都为默认空值,框架自动会触发校验报错,完全适配ASP.NET Core的自动模型校验逻辑。
方案2:低版本.NET 通用实现
如果你的项目运行在.NET 7及以下版本,框架没有提供开箱即用的单特性方案,你可以把反射校验逻辑封装到通用基类里,后续所有需要同类校验的请求类直接继承即可,不需要每个类重复写逻辑:
using System.ComponentModel.DataAnnotations; using System.Reflection; public abstract class UpdateRequestBase : IValidatableObject { public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { // 遍历当前类所有公开实例属性 var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties) { var value = prop.GetValue(this); // 判断属性是否非默认值(可空类型判断非null,值类型判断非默认值) if (value != null && !value.Equals(Activator.CreateInstance(prop.PropertyType))) { return Enumerable.Empty<ValidationResult>(); } } yield return new ValidationResult("至少需要设置一个更新属性"); } } // 业务请求类直接继承基类即可 public class UpdateAccountRequest : UpdateRequestBase { public bool? Disabled { get; set; } // 后续新增其他可更新属性无需修改校验逻辑 }
注意事项
所有可更新属性建议声明为可空类型(比如bool?、int?、string),避免值类型的默认值(比如int默认0、bool默认false)被误判为用户主动赋值。
内容的提问来源于stack exchange,提问作者user17365408
相关产品推荐
相关产品推荐

