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

.NET Core中PUT请求后立即发起同控制器GET请求返回HTTP 400(无效请求动词)的异常问题求助

诊断与解决.NET Core中PUT后立即GET出现400 Invalid Verb的问题

看起来你遇到的这个问题非常典型,结合你给出的异常表现和代码,我判断大概率和**HTTP连接复用(Keep-Alive)**以及客户端请求发送逻辑有关。下面我会一步步拆解原因并给出针对性的解决方案:

核心原因分析

你提到的几个特殊表现已经给出了关键线索:

  • 断点后正常:断点让客户端等待了足够久,TCP连接已经超时关闭,后续GET请求使用了新连接;
  • 改POST正常:POST和PUT在客户端/服务器的连接复用处理逻辑存在差异;
  • 等一分钟正常:连接空闲超时自动关闭,重新建立连接后请求恢复正常;
  • Postman正常:Postman的请求发送逻辑会正确处理连接复用,不会携带旧请求的残留数据。

本质问题是:客户端在PUT请求完成后,立即复用了同一个TCP连接发送GET请求,但请求报文出现了异常(比如请求verb没有正确覆盖、请求头格式错误),导致Kestrel服务器直接识别为无效请求,没有进入MVC路由管道(所以你的GET方法根本没被调用)。

具体解决方案

1. 优先排查客户端请求逻辑

这是最可能的根源,先从客户端入手:

  • 确保每次请求都使用独立的请求对象(比如用HttpClient时,不要复用同一个HttpRequestMessage实例,每次GET/PUT都新建);
  • 检查PUT请求完成后,是否正确关闭了请求流、释放了相关资源,避免残留数据影响后续复用连接;
  • 临时在客户端添加Connection: Close请求头,禁用Keep-Alive,如果问题消失,就坐实了连接复用的问题,再针对性优化客户端的连接管理逻辑。

2. 调整PUT方法为异步实现

你的PUT方法用了同步数据库操作,可能导致响应没有完全完成就返回给客户端,连接还处于半开状态。改成异步版本确保所有操作完成后再响应:

[HttpPut("JoinMatch/{matchId}")]
public async Task<ActionResult> JoinMatch(Guid matchId)
{
    string nickGuest = User.FindFirst(ClaimTypes.Name)?.Value;
    Match match = await context.Matches.Where(m => m.Id.Equals(matchId)).FirstOrDefaultAsync();
    if (match == null)
        return NotFound(new ResponseContainer<List<Match>>() { Error = "There is no match with that Id" });
    if (match.PlayerGuest != null)
        return Conflict(new ResponseContainer<List<Match>>() { Error = "The match is no more available" });
    Player guest = await context.Players.FindAsync(nickGuest);
    if (guest == null)
        return NotFound(new ResponseContainer<List<Match>>() { Error = "No player found" });
    match.JoinMatch(guest);
    match.PlayerGuest = guest;
    context.Update(match);
    await context.SaveChangesAsync();
    return Ok(new ResponseContainer<Match>() { Response = match });
}

3. 调整Kestrel服务器的连接配置

在Program.cs中修改Kestrel的连接超时设置,缩短空闲连接的存活时间,减少复用异常的概率:

builder.WebHost.ConfigureKestrel(options =>
{
    // 缩短空闲连接超时时间,默认是2分钟,改成30秒
    options.Limits.IdleTimeout = TimeSpan.FromSeconds(30);
});

4. 启用Kestrel详细日志排查

如果以上方法都没解决,可以开启Kestrel的Debug级日志,查看无效请求的具体内容,定位到底是客户端发送了什么异常数据:
在appsettings.json中添加:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore.Kestrel": "Debug"
    }
  }
}

日志会显示Kestrel接收到的原始请求报文,能帮你精准定位问题。

5. 检查反向代理(如果有)

如果你的服务部署在IIS、Nginx等代理后面,检查代理的连接复用配置,比如IIS的重写规则是否篡改了请求verb,或者代理是否正确处理了HTTP/1.1的Keep-Alive头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:57:43