.NET Core Post接口无法读取FromQuery参数且报错需非空请求体
解决.NET Core HttpPost仅使用Query参数、忽略请求体及正确应用Query参数到Linq查询的问题
一、先搞定“非空请求体必填”的异常
你遇到的400错误根源很明确:方法参数里的BillingInfo billingInfoCreateDto是复杂类型,ASP.NET Core默认会尝试从请求体绑定它,但你测试时没传请求体,所以触发了验证错误。
解决这个问题的核心是不让框架尝试从请求体绑定这个对象——直接把它从方法参数里删掉,在方法内部手动实例化就行。修改后的方法签名如下:
[HttpPost] public async Task<IActionResult> CreateBillingInfo([FromQuery]int projectId)
二、正确用Query参数做Linq查询+处理导航属性
接下来调整内部逻辑,确保projectId被正确使用,同时妥善保留Project导航属性:
- 先校验Project是否存在:避免后续查询空数据或抛出异常
- 手动创建BillingInfo实例:自己填充所有需要的属性,不用依赖请求体
- 合理关联导航属性:如果你的EF Core实体配置了正确的外键关系,其实只赋值
ProjectId框架就会自动处理导航属性,但你要保留Project属性的话,手动查询后赋值也没问题
修改后的完整代码示例:
[HttpPost] public async Task<IActionResult> CreateBillingInfo([FromQuery]int projectId) { // 角色校验:加个空值判断避免空引用异常 var role = User.FindFirst(ClaimTypes.Role)?.Value; if (role != "admin") { return BadRequest("Available only for admin"); } // 先确认目标Project存在 var targetProject = await _context.Projects.FirstOrDefaultAsync(x => x.Id == projectId); if (targetProject == null) { return NotFound($"Project with ID {projectId} doesn't exist."); } // 一次查询获取所有虚拟机资源数据,避免三次重复查询提升性能 var vmResources = await _context.VirtualMachines .Where(x => x.Project.Id == projectId) .Select(x => new { x.Ram, x.DiskSize, x.CPU }) .ToListAsync(); // 计算资源总和 var totalRam = vmResources.Sum(x => x.Ram); var totalDiskSize = vmResources.Sum(x => x.DiskSize); var totalCpu = (short)vmResources.Sum(x => x.CPU); // 手动实例化并填充BillingInfo var newBillingInfo = new BillingInfo { Ram = totalRam, DiskSize = totalDiskSize, Cpu = totalCpu, BeginApply = DateTime.Now.Date.AddHours(DateTime.Now.Hour), // 简化日期处理 EndApply = DateTime.Now.Date.AddHours(DateTime.Now.Hour + 1), ProjectId = projectId, Project = targetProject // 保留导航属性赋值 }; _context.BillingInfos.Add(newBillingInfo); await _context.SaveChangesAsync(); return StatusCode(201); }
额外小优化
- 把三次独立的Sum查询改成一次查询后计算,减少数据库交互次数
- 给角色校验加了空值判断,避免用户没携带Role-Claim时抛出异常
- 简化了日期处理逻辑,用更直观的写法替代
Trim
现在你再用Postman发送不带请求体的POST请求http://localhost:5000/api/billinginfo?projectId=59,就能正常执行了,Query参数也会正确应用到Linq查询中,导航属性也能正常保留。
内容的提问来源于stack exchange,提问作者Arzu Suleymanov
相关产品推荐
相关产品推荐

