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

ASP.NET Core向Azure Blob传大文件遇OutOfMemoryException求助

解决ASP.NET Core上传大文件到Azure Blob时的OutOfMemoryException问题

这个错误很典型——默认情况下,ASP.NET Core处理multipart/form-data表单上传时,会把整个文件内容缓冲到内存或者服务器临时磁盘中,当你上传256MB的文件时,加上应用本身的内存占用,很容易就超过WebApp的3.5GB内存限制,触发OutOfMemoryException。

下面是一步步的解决方案,核心思路是流式分块上传,让文件内容不经过完整加载到内存,直接流到Azure Blob存储:

1. 先配置ASP.NET Core允许大文件上传

首先要调整应用的请求大小限制,不然Kestrel或者中间件会直接拒绝大文件请求。在Program.cs里添加以下配置:

builder.Services.Configure<FormOptions>(options =>
{
    // 设置单个文件的最大大小(这里设为500MB,可根据需求调整)
    options.MultipartBodyLengthLimit = 524288000;
    // 设置整个表单的最大大小
    options.ValueLengthLimit = 524288000;
});

// 配置Kestrel的请求限制
builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxRequestBodySize = 524288000; // 500MB
});

2. 使用Azure Blob的流式分块上传API

不要用传统的把文件读进byte[]的方式,而是直接用文件流配合Azure.Storage.Blobs的UploadAsync方法,它支持自动分块上传,而且会流式处理内容,不会把整个文件加载到内存。

控制器示例代码

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.AspNetCore.Mvc;

public class UploadFilesController : Controller
{
    private readonly BlobServiceClient _blobServiceClient;

    // 依赖注入BlobServiceClient(建议从配置中获取连接字符串)
    public UploadFilesController(BlobServiceClient blobServiceClient)
    {
        _blobServiceClient = blobServiceClient;
    }

    [HttpPost]
    public async Task<IActionResult> Post()
    {
        if (!Request.HasFormContentType)
        {
            return BadRequest("请求不是multipart/form-data类型");
        }

        var formFile = Request.Form.Files.FirstOrDefault();
        if (formFile == null || formFile.Length == 0)
        {
            return BadRequest("没有选择要上传的文件");
        }

        try
        {
            // 获取容器客户端(替换为你的容器名称)
            var containerClient = _blobServiceClient.GetBlobContainerClient("your-container-name");
            await containerClient.CreateIfNotExistsAsync();

            // 获取blob客户端,用文件名作为blob名称(可根据需求修改命名规则)
            var blobClient = containerClient.GetBlobClient(formFile.FileName);

            // 配置上传选项,启用流式分块
            var uploadOptions = new BlobUploadOptions
            {
                ParallelTransferOptions = new ParallelTransferOptions
                {
                    // 设置分块大小(建议在4MB到100MB之间,这里用32MB)
                    BlockSize = 33554432, // 32 * 1024 * 1024
                    // 设置并发上传的分块数,根据服务器资源调整
                    MaxConcurrency = 2
                },
                // 如果需要覆盖已存在的blob,设置为true
                Overwrite = true
            };

            // 直接用文件流上传,该方法会自动处理分块,不会把整个文件加载到内存
            using var fileStream = formFile.OpenReadStream();
            await blobClient.UploadAsync(fileStream, uploadOptions);

            return Ok($"文件 {formFile.FileName} 上传成功");
        }
        catch (Exception ex)
        {
            // 可添加日志记录逻辑
            return StatusCode(500, $"上传失败:{ex.Message}");
        }
    }
}

3. 额外优化建议

  • 坚持异步操作:确保所有Azure Blob的操作都使用异步方法(比如UploadAsync),避免阻塞线程导致资源浪费。
  • 灵活调整分块参数:如果WebApp网络带宽较好,可适当增大BlockSize(但不要超过Azure Blob单个分块的100MB上限);如果带宽一般,减小分块大小并降低MaxConcurrency,避免占用过多网络资源。
  • 监控内存指标:可以在Azure Portal中查看WebApp的内存使用情况,确认大文件上传时内存占用处于合理范围。

这样调整后,你的应用就可以流式处理大文件上传,不会把整个文件加载到内存,也就避免了OutOfMemoryException的问题。

内容的提问来源于stack exchange,提问作者Artem Danchenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:59:24