You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多输入模型至少一个必填字段验证实现求助

嘿,这个多字段至少填一个的验证需求我之前帮好多开发者处理过,给你两种实用的解决方案,看哪种更适配你的项目:

方法一:自定义验证属性(.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:46:28