Windows Server 2019 IIS上ASP.NET Core客户端断开异常排查与修复咨询
异常分析与解决方案:The client has disconnected (0x80070040)
异常概述
日志中出现The client has disconnected异常,伴随内部错误码The specified network name is no longer available. (0x80070040),每周仅出现约3次,难以复现,应用部署在Windows Server 2019的IIS环境中。
可能成因
- 客户端主动断开连接:ASP.NET Core在通过
[FromBody]绑定模型、读取请求体的过程中,客户端提前关闭了连接,导致IIS无法继续读取请求内容,触发该COM错误。 - 网络临时中断:服务器与客户端之间的网络连接出现短暂波动,请求体传输中途失败,引发连接重置异常。
- 中间件逻辑问题:当前中间件在执行后续管道(
_next)后再读取请求体,不仅可能因流已被读取无法获取内容,且未针对性处理客户端断开类异常,导致这类非业务异常被抛出扩散。
修复方案与代码修改
1. 针对性捕获连接异常
针对客户端断开类的ConnectionResetException,增加条件捕获,仅记录日志而不重新抛出,避免不必要的异常扩散。
2. 正确处理请求体读取
提前启用请求体缓冲,读取后重置流位置,确保后续管道(如MVC控制器)能正常读取请求体,同时避免因重复读取导致的问题。
修改后的中间件代码
public class RequestHandlingMiddleware { private readonly RequestDelegate _next; public RequestHandlingMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext httpContext, IWallesterLogger logger) { string rawRequestBody = null; try { // 启用请求体缓冲,支持多次读取 if (httpContext.Request.ContentLength > 0 || !httpContext.Request.Body.CanSeek) { httpContext.Request.EnableBuffering(); using var reader = new StreamReader(httpContext.Request.Body, leaveOpen: true); rawRequestBody = await reader.ReadToEndAsync(); // 重置流位置,让后续中间件/控制器正常读取 httpContext.Request.Body.Position = 0; } await _next(httpContext); // 仅在请求正常处理时记录请求信息 if (httpContext.Response.StatusCode < 400) { await logger.Log(WallesterLogSection.RequestInfoLog, httpContext.Request.Path.Value, new { Path = httpContext.Request.Path.Value, Method = httpContext.Request.Method, RawRequestBody = rawRequestBody, Headers = httpContext.Request.Headers }); } } catch (ConnectionResetException ex) when (ex.InnerException is System.Runtime.InteropServices.COMException comEx && comEx.ErrorCode == 0x80070040) { // 记录客户端断开的异常,不重新抛出 await logger.Log(ex, WallesterLogSection.Exception); } catch (Exception ex) { await HandleExceptionAsync(httpContext, ex, logger); throw; } } private async Task HandleExceptionAsync(HttpContext context, Exception exception, IWallesterLogger logger) { await logger.Log(exception, WallesterLogSection.Exception); } } // 扩展方法保持不变 public static class LoggerkMiddlewareExtensions { public static IApplicationBuilder UseLoggerMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<RequestHandlingMiddleware>(); } }
额外优化建议
- 检查IIS站点的连接超时设置,调整为合理时长(默认120秒),避免因超时导致的异常。
- 监控触发异常的请求来源,排查是否有特定客户端或网络环境频繁出现连接中断。
内容的提问来源于stack exchange,提问作者Brivvirs
相关产品推荐
相关产品推荐

