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

为何API中设默认值的可选查询参数仍报‘Field is Required’错误?

问题:API查询参数设默认值仍被判定为必填

控制器代码

[HttpGet]
[Authorize]
public async Task<ActionResult<GetProfessionalsQueryResponse>> GetAllAsync([FromQuery]string modalityId = "")
{
    return Ok(await _mediator.Send(new GetProfessionalsQuery { ModalityId = modalityId }));
}

错误响应

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-501a973003a36918de9e22ee2bab9936-73e986dd9121e81a-00",
"errors": {
"modalityId": [
"The modalityId field is required."
]
}
}

现象

  • 提供modalityId参数值时,API正常返回筛选结果
  • 不提供该参数时,返回上述400验证错误,且调试发现未进入GetAllAsync方法
  • 已为参数设置空字符串默认值,预期该参数为非必填

相关代码(Program.cs)

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddApplicationServices();

        builder.Services.AddPersistenceServices(builder.Configuration);

        builder.Services.AddInfrastructureServices(builder.Configuration);

        builder.Services.AddHttpContextAccessor();

        builder.Services.AddControllers().AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        });

        builder.Services.AddCors(options =>
        {
            options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
        });

        builder.Services.AddEndpointsApiExplorer();

        builder.Services.AddSwaggerGen();

        var app = builder.Build();
     
        app.UseSwagger();

        app.UseSwaggerUI();

        app.UseHttpsRedirection();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseMiddleware<ExceptionHandlerMiddleware>();

        app.MapControllers();

        app.Run();
    }
}

补充说明

GetProfessionalsQuery无任何验证逻辑。


解决方案

这种情况是ASP.NET Core模型验证机制导致的:非可空引用类型的查询参数,框架默认会判定为必填,即使设置了默认值。可以通过以下方式解决:

  1. 将参数改为可空引用类型
    明确告知框架参数允许为null,修改后的方法定义如下:

    public async Task<ActionResult<GetProfessionalsQueryResponse>> GetAllAsync([FromQuery]string? modalityId = "")
    

    也可以直接去掉默认值,因为可空类型本身支持不传递参数:

    public async Task<ActionResult<GetProfessionalsQueryResponse>> GetAllAsync([FromQuery]string? modalityId)
    
  2. 检查全局验证配置(可选)
    若项目启用了全局严格验证规则,可在AddControllers时调整验证行为:

    builder.Services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        })
        .ConfigureApiBehaviorOptions(options =>
        {
            // 自定义验证失败响应逻辑(按需配置)
            options.InvalidModelStateResponseFactory = context =>
            {
                return new BadRequestObjectResult(context.ModelState);
            };
        });
    

核心逻辑:ASP.NET Core对非可空引用类型的查询参数会强制验证存在性,改为可空类型后,框架会识别该参数为可选,自动应用默认值或允许null传入。

内容的提问来源于stack exchange,提问作者adamasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:22:39