多输入模型至少一个必填字段验证实现求助
嘿,这个多字段至少填一个的验证需求我之前帮好多开发者处理过,给你两种实用的解决方案,看哪种更适配你的项目:
方法一:自定义验证属性(.NET原生实现)
这种方式不用引入任何第三方库,完全靠.NET自带的数据验证体系就能搞定,适合简单场景。
首先写一个自定义的验证属性类,继承自ValidationAttribute,重写核心的验证逻辑:
using System.ComponentModel.DataAnnotations; using System.Reflection; public class AtLeastOneRequiredAttribute : ValidationAttribute { private readonly string[] _targetPropertyNames; // 构造函数传入需要检查的字段名 public AtLeastOneRequiredAttribute(params string[] targetPropertyNames) { _targetPropertyNames = targetPropertyNames; ErrorMessage = $"至少需要填写以下字段中的一个:{string.Join(", ", _targetPropertyNames)}"; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // 遍历所有目标字段,检查是否有非空值 foreach (var propertyName in _targetPropertyNames) { PropertyInfo property = validationContext.ObjectType.GetProperty(propertyName); if (property == null) { return new ValidationResult($"指定的字段 {propertyName} 不存在于模型中"); } object propertyValue = property.GetValue(validationContext.ObjectInstance); if (propertyValue != null && !string.IsNullOrWhiteSpace(propertyValue.ToString())) { // 只要有一个字段有值,直接返回验证通过 return ValidationResult.Success; } } // 所有字段都为空,返回验证失败消息 return new ValidationResult(ErrorMessage); } }
接着把这个属性标记到你的Search模型上(注意类名首字母大写,符合C#命名规范哦):
// 把需要检查的字段名传给自定义属性 [AtLeastOneRequired(nameof(Sample1), nameof(Sample2), nameof(Sample3))] public class Search { public string Sample1 { get; set; } public string Sample2 { get; set; } public string Sample3 { get; set; } }
最后在控制器里触发验证就行,和原生模型验证的使用方式完全一致:
[HttpPost] public IActionResult PerformSearch([FromBody] Search searchModel) { if (!ModelState.IsValid) { // 返回验证错误信息 return BadRequest(ModelState); } // 这里写你的业务逻辑 return Ok("搜索请求已接收"); }
方法二:使用FluentValidation(更灵活的第三方方案)
如果你的项目已经在使用FluentValidation,或者需要更复杂、易扩展的验证逻辑,这个方法会更顺手。
第一步先安装NuGet包:
# 使用.NET CLI安装 dotnet add package FluentValidation.AspNetCore
然后创建对应的模型验证器类:
using FluentValidation; public class SearchValidator : AbstractValidator<Search> { public SearchValidator() { // 直接编写逻辑:三个字段至少有一个非空 RuleFor(model => model) .Must(HaveAtLeastOneNonEmptyField) .WithMessage("Sample1、Sample2、Sample3中必须填写至少一个字段"); } private bool HaveAtLeastOneNonEmptyField(Search model) { return !string.IsNullOrWhiteSpace(model.Sample1) || !string.IsNullOrWhiteSpace(model.Sample2) || !string.IsNullOrWhiteSpace(model.Sample3); } }
接下来在项目的启动配置里注册验证器(以.NET 6+的Program.cs为例):
builder.Services.AddControllers() // 注册当前程序集里的所有FluentValidation验证器 .AddFluentValidation(config => config.RegisterValidatorsFromAssemblyContaining<SearchValidator>());
这样当模型绑定的时候,FluentValidation会自动执行验证,不符合要求的话ModelState.IsValid会直接变成false,你只需要在控制器里判断处理就行。
小提示
- 原生自定义属性适合轻量场景,零依赖;FluentValidation在复杂验证场景下更易维护和扩展。
- 记得把你的模型类名从
search改成Search,这是C#的命名规范,能让代码更易读哦。
内容的提问来源于stack exchange,提问作者user3643560
相关产品推荐
相关产品推荐

