为何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模型验证机制导致的:非可空引用类型的查询参数,框架默认会判定为必填,即使设置了默认值。可以通过以下方式解决:
将参数改为可空引用类型
明确告知框架参数允许为null,修改后的方法定义如下:public async Task<ActionResult<GetProfessionalsQueryResponse>> GetAllAsync([FromQuery]string? modalityId = "")也可以直接去掉默认值,因为可空类型本身支持不传递参数:
public async Task<ActionResult<GetProfessionalsQueryResponse>> GetAllAsync([FromQuery]string? modalityId)检查全局验证配置(可选)
若项目启用了全局严格验证规则,可在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
相关产品推荐
相关产品推荐

