.NET6读取请求体时随机出现MemoryPool已释放异常
问题解决:中间件读取请求体随机出现ObjectDisposedException错误
错误根源
你遇到的System.ObjectDisposedException: Cannot access a disposed object. Object name: 'MemoryPool'错误,本质是StreamReader的using语句会在代码块结束时自动释放它包装的context.Request.Body流。即便你在块内重置了流的Position,后续中间件尝试访问这个已被释放的请求体流时,就会触发异常。随机性是因为部分请求的后续处理不需要再读取请求体,所以不会报错;而那些后续需要读取请求体的请求,就会抛出这个异常。
解决办法
正确的做法是先将请求体内容复制到**内存流(MemoryStream)**中,内存流支持多次读取且不会被自动释放,之后替换原请求体流为这个内存流,确保后续中间件也能正常访问。
修改后的代码示例
// 将原请求体复制到内存流 var memoryStream = new MemoryStream(); await context.Request.Body.CopyToAsync(memoryStream); memoryStream.Position = 0; // 从内存流读取请求体内容 requestBody = await new StreamReader(memoryStream).ReadToEndAsync(); // 重置内存流位置,方便后续中间件读取 memoryStream.Position = 0; // 替换原请求体流为内存流 context.Request.Body = memoryStream;
额外说明
- 不要用
using包裹读取内存流的StreamReader,因为StreamReader默认会在释放时关闭基础流(也就是内存流),导致后续中间件无法访问。 - ASP.NET Core默认的请求体流是不可重读的,通过内存流替换是处理请求体重读场景的标准方案,能彻底避免流被提前释放的问题。
内容的提问来源于stack exchange,提问作者tushar bansal
相关产品推荐
相关产品推荐

