You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Asp.Net Core 5.0 Web API(IIS 10环境)中实现真正无限制的文件上传?

解决Asp.Net Core 5.0 + IIS 10无限制文件上传的方案

我完全理解你的困扰——maxAllowedContentLength的4GB上限确实卡死了大文件上传的需求,毕竟uint类型的最大值就是这么多,没法直接突破。结合你用的Asp.Net Core 5.0和IIS 10环境,这里有两个最可行的解决方案:

方案一:采用分块上传(推荐)

这是处理超大文件上传的行业通用方案,不仅能绕过IIS的4GB限制,还能支持断点续传、降低服务器内存压力,体验更友好。核心思路是把大文件切成若干小片段(比如100MB/块),前端分批次上传,后端接收后再拼接成完整文件。

配置调整

  1. Asp.Net Core后端配置
    在处理上传的控制器Action上添加特性,放宽单请求的大小限制(因为每个块的大小远小于4GB):

    [RequestSizeLimit(104857600)] // 100MB,对应单个块的大小
    [RequestFormLimits(MultipartBodyLengthLimit = 104857600)]
    public async Task<IActionResult> UploadChunk()
    {
        // 核心逻辑:
        // 1. 接收块编号、总块数、唯一文件ID等参数
        // 2. 将当前块保存到临时目录,命名为 {文件ID}_{块编号}
        // 3. 当所有块上传完成后,按顺序拼接成完整文件,再删除临时文件
        var file = Request.Form.Files["chunk"];
        var chunkIndex = int.Parse(Request.Form["chunkIndex"]);
        var totalChunks = int.Parse(Request.Form["totalChunks"]);
        var fileId = Request.Form["fileId"];
    
        var tempPath = Path.Combine(Path.GetTempPath(), "UploadChunks", fileId);
        Directory.CreateDirectory(tempPath);
    
        using var stream = new FileStream(Path.Combine(tempPath, $"{chunkIndex}"), FileMode.Create);
        await file.CopyToAsync(stream);
    
        if (chunkIndex == totalChunks - 1)
        {
            // 合并所有块
            using var finalStream = new FileStream(Path.Combine("Uploads", fileId), FileMode.Create);
            for (int i = 0; i < totalChunks; i++)
            {
                var chunkPath = Path.Combine(tempPath, $"{i}");
                using var chunkStream = new FileStream(chunkPath, FileMode.Open);
                await chunkStream.CopyToAsync(finalStream);
                System.IO.File.Delete(chunkPath);
            }
            Directory.Delete(tempPath);
        }
    
        return Ok("Chunk uploaded successfully");
    }
    
  2. IIS配置(web.config)
    maxAllowedContentLength设为单个块的大小即可,比如100MB:

    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="104857600"/> <!-- 100MB -->
        </requestFiltering>
      </security>
    </system.webServer>
    

优势

  • 完全绕过IIS的4GB限制,支持任意大小的文件上传
  • 支持断点续传(前端记录已上传的块,重试时只传未完成的部分)
  • 降低服务器内存占用,避免单个大请求耗尽资源

方案二:IIS反向代理+Kestrel直接处理请求

如果你不想修改前端的上传逻辑,也可以让IIS只做反向代理,把请求转发给Asp.Net Core的Kestrel服务器,由Kestrel直接处理大文件上传,绕过IIS的maxAllowedContentLength限制。

配置步骤

  1. 安装IIS模块
    先安装应用程序请求路由(ARR)URL Rewrite模块,这是IIS做反向代理的基础。

  2. Asp.Net Core后端配置
    Program.cs(或Startup.cs)中配置Kestrel允许无限制的请求体大小:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseKestrel(options =>
                {
                    options.Limits.MaxRequestBodySize = null; // 设置为null表示无限制
                });
            });
    

    同时在上传Action上添加特性:

    [RequestSizeLimit(null)]
    [RequestFormLimits(MultipartBodyLengthLimit = null)]
    public async Task<IActionResult> UploadFile()
    {
        var file = Request.Form.Files[0];
        var savePath = Path.Combine("Uploads", file.FileName);
        using var stream = new FileStream(savePath, FileMode.Create);
        await file.CopyToAsync(stream);
        return Ok("File uploaded successfully");
    }
    
  3. IIS反向代理配置(web.config)
    添加重写规则转发请求到Kestrel,同时禁用IIS的请求缓冲,避免触发maxAllowedContentLength检查:

    <system.webServer>
      <!-- 重写规则:转发请求到Kestrel的端口(比如5000) -->
      <rewrite>
        <rules>
          <rule name="ReverseProxyToKestrel" stopProcessing="true">
            <match url="(.*)" />
            <action type="Rewrite" url="http://localhost:5000/{R:1}" />
          </rule>
        </rules>
      </rewrite>
      <!-- 禁用IIS的上传预读取缓冲,避免读取整个请求体 -->
      <serverRuntime uploadReadAheadSize="0" />
      <!-- 保留maxAllowedContentLength的最大值,但因为禁用缓冲,IIS不会检查整个请求体 -->
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="4294967295"/>
        </requestFiltering>
      </security>
    </system.webServer>
    

注意事项

  • 要确保Kestrel服务稳定运行,可配置成Windows服务托管
  • 大文件上传时,服务器的磁盘空间和网络带宽要足够
  • 该方案依赖IIS的反向代理功能,需要服务器管理员权限安装模块

内容的提问来源于stack exchange,提问作者Y F

火山引擎 最新活动