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

.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导航属性:

  1. 先校验Project是否存在:避免后续查询空数据或抛出异常
  2. 手动创建BillingInfo实例:自己填充所有需要的属性,不用依赖请求体
  3. 合理关联导航属性:如果你的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:43:16