使用C# Stream在网页展示PDF刷新报ObjectDisposedException错误如何解决
问题根因
你遇到的报错本质是两点原因导致的:
- ASP.NET Core框架在返回
FileResult之后,会自动释放传入的Stream对象,你第一次请求PDF接口的时候,documentData里存的PdfFileStream就已经被关闭了,刷新页面第二次访问同一个流对象自然会抛出ObjectDisposedException。 - 你当前是把
DocumentData作为共享服务注入,预存了同一个Stream对象全局复用,没有每次请求PDF都重新获取新的流。
修复方案
你需要调整流的获取逻辑,保证每次请求PDF接口时拿到的都是未被释放的可用流,两种方案可以按需选择:
方案1:每次请求重新从API拉取流(适合大体积PDF、不想占用服务端内存的场景)
1.1 修改DocumentData,把预存流改成动态拉取流的方法
public class DocumentData { public string Filename { get; set; } = "long_line_file_ORIGINAl.pdf"; // 替换原有的Stream属性,封装从API拉取流的逻辑 public async Task<Stream> FetchPdfStreamFromApiAsync() { // 这里替换成你原本从上游API获取PDF流的代码,每次调用都会发起新请求返回新的Stream // 示例代码: // var httpClient = new HttpClient(); // var response = await httpClient.GetAsync("你的上游PDF接口地址", HttpCompletionOption.ResponseHeadersRead); // return await response.Content.ReadAsStreamAsync(); } }
1.2 调整控制器的PDF接口逻辑
public class Files1Controller : Controller { private IWebHostEnvironment hostingEnvironment; private readonly DocumentData documentData; public Files1Controller(IWebHostEnvironment hostingEnvironment, DocumentData documentData) { this.hostingEnvironment = hostingEnvironment; this.documentData = documentData; } [HttpGet] public IActionResult Index() { return View(documentData); } // 改成异步方法,每次请求都拉取新的流 public async Task<IActionResult> PdfViewerNewTab() { var pdfStream = await documentData.FetchPdfStreamFromApiAsync(); // 框架会在响应结束后自动释放当前流,不需要手动处理 return File(pdfStream, "application/pdf"); } }
方案2:缓存PDF字节数组(适合小体积PDF、想减少上游API调用的场景)
如果PDF体积不大,你可以把PDF内容缓存为字节数组,不需要每次都调用上游API,也不会有流被提前释放的问题:
// 修改DocumentData public class DocumentData { public string Filename { get; set; } = "long_line_file_ORIGINAl.pdf"; // 字节数组缓存 private byte[] _pdfBytesCache; public async Task<byte[]> GetPdfBytesAsync() { // 仅首次调用时拉取API if (_pdfBytesCache == null) { // 这里替换成你从API拉取PDF的逻辑,读成字节数组 // var httpClient = new HttpClient(); // _pdfBytesCache = await httpClient.GetByteArrayAsync("你的上游PDF接口地址"); } return _pdfBytesCache; } } // 控制器接口调整为返回字节数组 public async Task<IActionResult> PdfViewerNewTab() { var pdfBytes = await documentData.GetPdfBytesAsync(); return File(pdfBytes, "application/pdf"); }
内容的提问来源于stack exchange,提问作者gh99
相关产品推荐
相关产品推荐

