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

IFormFileCollection上传Azure Blob报无法访问已释放对象错误

问题原因

你触发的Cannot access a disposed object. Object name: 'FileBufferingReadStream'错误,本质是IFormFile关联的FileBufferingReadStream生命周期由ASP.NET Core请求管道托管,出现提前释放的常见诱因有三个:

  • 直接将IFormFile.OpenReadStream()返回的原始流传给Blob上传方法,没有对流做独立拷贝:当请求上下文切换、表单资源被框架提前回收时,流会被自动释放,上传逻辑读取流时就会触发对象已释放错误
  • 旧版Azure Blob SDK(Microsoft.Azure.Storage.Blob)的UploadFromStreamAsync方法不会自动重置流读取位置,如果流位置不在起始点,会触发读取失败,部分场景下会间接导致流被框架回收
  • 错误的异常捕获写法throw e会清空原始异常堆栈,导致你无法定位流释放的真实触发点,同时如果将IFormFileCollection传到脱离请求管道的后台线程、延迟任务中读取,会因为请求结束后流被释放100%触发该错误
修复步骤

1. 配置请求表单缓冲

在Program.cs中配置表单选项,保证文件上传场景下请求体缓冲正常开启,避免大文件场景下流被提前回收:

builder.Services.Configure<FormOptions>(options =>
{
    // 根据业务需求调整单文件/请求体大小上限,示例为100MB
    options.MultipartBodyLengthLimit = 100 * 1024 * 1024;
    options.BufferBody = true;
});

2. 修正Blob上传逻辑

不要直接使用IFormFile返回的原始流上传,先将文件内容拷贝到自己控制生命周期的内存流中,上传前重置流位置:

public async Task UploadAsync(IFormFileCollection files, string directoryName)
{
    var blobContainer = await _azureBlobConnectionFactory.GetBlobContainer();
    CloudBlobDirectory directory = blobContainer.GetDirectoryReference(directoryName);
    for (int i = 0; i < files.Count; i++)
    {
        IFormFile file = files[i];
        CloudBlockBlob blockblob = directory.GetBlockBlobReference(file.FileName);
        // 新建独立内存流拷贝文件内容,生命周期由当前代码块控制,不受请求管道回收影响
        using (var uploadStream = new MemoryStream())
        {
            await file.CopyToAsync(uploadStream);
            uploadStream.Position = 0; // 将流读取指针重置到起始位置
            await blockblob.UploadFromStreamAsync(uploadStream);
        }
    }
}

3. 修正业务层异常写法

删除无意义的异常包装,不要用throw e破坏异常堆栈,同时确保上传逻辑在当前请求生命周期内执行,不要把IFormFile对象传递到请求结束后才运行的延迟任务、后台队列中:

public async Task<bool> UploadToBlob(DocumentModel model,string directorypath)
{
    await _blobService.UploadAsync(model.Files, "Documents/dummy.pdf");
    return true;
    
    // 如果需要加异常日志,按如下写法,不要用throw e
    // catch(Exception e)
    // {
    //     _logger.LogError(e, "Blob文件上传失败");
    //     throw;
    // }
}

补充建议:如果项目还在使用旧版Microsoft.Azure.Storage.Blob包,建议迁移到新版Azure.Storage.Blobs SDK,新版SDK对流处理的兼容性更好,上传方法会自动处理流位置,能减少很多流相关的异常。

内容的提问来源于stack exchange,提问作者Md Aslam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 01:01:01