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

解决ASP.NET Core在IIS下返回413时出现502.3错误的问题

问题原因分析

这个问题我之前也碰到过,核心是Kestrel和IIS作为反向代理时的请求处理逻辑差异导致的:

当你通过[RequestSizeLimit]特性或IHttpMaxRequestBodySizeFeature设置Kestrel的最大请求体限制时,Kestrel在检测到请求体超过限制的瞬间会直接中断TCP连接,而不是正常返回413响应。

而IIS(包括IIS Express)作为反向代理,它期望后端的Kestrel服务返回标准的HTTP响应头和内容。一旦Kestrel突然中断连接,IIS无法识别这是“请求过大”的合法场景,会将其判定为后端服务异常,从而返回HTTP Error 502.3 - Bad Gateway错误。

这也是为什么你手动返回413时IIS能正常工作——因为这是一个标准的HTTP响应,IIS会正常转发给客户端。

解决方案

针对这个问题,有两种可靠的解决思路:

1. 让IIS提前拦截过大请求(推荐)

在IIS层面配置请求大小限制,让IIS在请求到达Kestrel之前就拦截超过大小的请求,直接返回413响应。这样可以完全避免Kestrel触发连接中断的行为。

需要修改站点的web.config文件,添加requestLimits配置:

<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- 单位是字节,和你的Kestrel限制保持一致(1024) -->
        <requestLimits maxAllowedContentLength="1024" />
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

配置完成后,IIS会直接拦截超过1KB的请求,返回标准的413响应,不会再出现502.3错误。

2. 手动处理请求大小检查,避免Kestrel中断连接

如果你不想依赖IIS的配置,可以在代码层面手动检查请求体大小,自己返回413响应,而不是依赖Kestrel的内置限制。

修改你的控制器代码,先检查请求长度(如果客户端发送了Content-Length头),然后读取请求体时限制读取的字节数,判断是否超过限制:

[Route("api/values")]
public class ValuesController : Controller
{
    private const int MaxRequestSize = 1024;

    [HttpPost]
    public IActionResult Post()
    {
        // 先检查ContentLength(如果客户端提供了这个头)
        if (Request.ContentLength.HasValue && Request.ContentLength > MaxRequestSize)
        {
            return StatusCode(StatusCodes.Status413PayloadTooLarge);
        }

        string echo = string.Empty;
        try
        {
            using (StreamReader sr = new StreamReader(Request.Body))
            {
                // 只读取MaxRequestSize字节,避免读取过多内容
                char[] buffer = new char[MaxRequestSize];
                int bytesRead = sr.Read(buffer, 0, MaxRequestSize);
                echo = new string(buffer, 0, bytesRead);

                // 如果读取后Stream还没到结尾,说明请求体超过了限制
                if (!sr.EndOfStream)
                {
                    return StatusCode(StatusCodes.Status413PayloadTooLarge);
                }
            }
        }
        catch (Exception ex)
        {
            // 捕获读取异常,统一返回413
            return StatusCode(StatusCodes.Status413PayloadTooLarge);
        }

        return Ok(echo);
    }
}

这种方式不管是Kestrel独立运行还是IIS代理,都能正常返回413响应,因为没有触发Kestrel的连接中断逻辑。

额外注意事项

如果你使用的是ASP.NET Core 3.1及以上版本,并且代码中使用了同步读取请求体的方式(比如StreamReader.ReadToEnd()),需要在Kestrel配置中允许同步IO:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            webBuilder.ConfigureKestrel(options =>
            {
                options.AllowSynchronousIO = true;
            });
        });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:00:10