Blazor WASM ApiController读取请求体致IIS进程崩溃求助
问题原因分析
1. 请求流未重置且被框架提前释放
ASP.NET Core 框架默认会在请求处理完成后自动释放请求流。如果你的代码读取流后没有重置流位置,或者未保留流的可访问状态,当应用池复用进程处理后续请求时,就会尝试访问已被释放的流,触发ObjectDisposedException。
- 错误示例:
var reader = new StreamReader(Request.Body); var body = await reader.ReadToEndAsync(); // 未重置流位置,后续框架操作(如日志、中间件)访问流时出错
2. 同步/异步IO混用导致流状态损坏
Blazor WASM 后端的 ASP.NET Core 应用默认禁用同步IO(AllowSynchronousIO = false)。如果代码混合使用同步读取(如ReadToEnd())和异步读取(如ReadToEndAsync()),会破坏流的内部状态,导致流被提前标记为已释放,后续请求复用进程时直接报错。
3. 进程内资源未清理导致状态污染
Windows Server 2019 的 IIS 应用池默认会复用进程处理请求。如果你的代码存在资源泄漏(比如静态变量持有请求流引用、未释放的流句柄),第一次请求的异常会污染进程内的上下文状态,后续所有请求都会继承损坏的状态,最终导致进程崩溃终止。
4. 未启用请求体缓冲/重读机制
ASP.NET Core 中请求流默认只能读取一次。如果你的业务场景需要多次读取请求体(比如中间件和控制器都要读取),但未在Program.cs中配置EnableBuffering()或EnableRewind(),第一次读取后流就会被关闭,后续访问直接触发异常。
- 正确配置示例:
app.Use(async (context, next) => { context.Request.EnableBuffering(); await next(); });
5. 流操作未用using管理资源
如果读取流的代码没有用using包裹StreamReader等流操作对象,会导致资源句柄未被正确释放,残留句柄在进程中累积,最终导致进程因资源耗尽而崩溃。
- 正确写法:
using var reader = new StreamReader(Request.Body); var body = await reader.ReadToEndAsync(); context.Request.Body.Position = 0; // 重置流位置,供后续中间件使用
内容的提问来源于stack exchange,提问作者Cleo
相关产品推荐
相关产品推荐

