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

使用C# Stream在网页展示PDF刷新报ObjectDisposedException错误如何解决

问题根因

你遇到的报错本质是两点原因导致的:

  1. ASP.NET Core框架在返回FileResult之后,会自动释放传入的Stream对象,你第一次请求PDF接口的时候,documentData里存的PdfFileStream就已经被关闭了,刷新页面第二次访问同一个流对象自然会抛出ObjectDisposedException。
  2. 你当前是把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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:15:10