如何在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/块),前端分批次上传,后端接收后再拼接成完整文件。
配置调整
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"); }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限制。
配置步骤
安装IIS模块:
先安装应用程序请求路由(ARR)和URL Rewrite模块,这是IIS做反向代理的基础。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"); }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




