解决ASP.NET Core Web API中“Multipart body length limit 16384 exceeded”报错
解决ASP.NET Core Web API大文件上传“Multipart body length limit 16384 exceeded”报错
兄弟,这个报错我之前折腾过好一阵子,结合你说的「用第三方控件正常、自己写逻辑就出问题」的情况,核心原因要么是你Angular端的请求构造不符合流式上传的要求,要么是后端的流式处理配置没完全到位。给你一步步拆解解决方案:
一、先确认后端流式上传的实现是否正确
首先得确保你是按照微软流式上传的思路来做的——不要用IFormFile参数,因为IFormFile会触发ASP.NET Core默认的表单绑定逻辑,而默认的单个Multipart段长度限制就是16KB,这正是报错的来源。正确的流式控制器代码应该是直接读取Request.Body,用MultipartReader逐段处理:
private readonly FormOptions _defaultFormOptions; // 通过构造注入获取默认表单配置 public FileController(IOptions<FormOptions> formOptions) { _defaultFormOptions = formOptions.Value; } [HttpPost("upload")] public async Task<IActionResult> Upload() { // 先验证请求是否为多部分表单类型 if (!Request.HasFormContentType) { return BadRequest("请求格式错误,需为multipart/form-data类型"); } // 获取请求的boundary(分隔符) var boundary = MultipartRequestHelper.GetBoundary( MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit); var reader = new MultipartReader(boundary, Request.Body); var section = await reader.ReadNextSectionAsync(); // 逐段读取表单内容 while (section != null) { var hasContentDisposition = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); // 识别文件段 if (hasContentDisposition && contentDisposition.DispositionType.Equals("form-data") && !string.IsNullOrEmpty(contentDisposition.FileName.Value)) { // 这里替换成你的文件保存逻辑 using var saveStream = new FileStream($"你的保存路径/{contentDisposition.FileName.Value}", FileMode.Create); await section.Body.CopyToAsync(saveStream); } section = await reader.ReadNextSectionAsync(); } return Ok(new { message = "文件上传成功" }); }
二、重点排查Angular端的上传逻辑(90%的问题出在这)
因为你用第三方控件没问题,说明后端是正常的,自己写的代码大概率在请求构造上有问题:
1. 必须用FormData构造请求,且不要手动设置Content-Type
Angular会自动给FormData请求添加带正确boundary的Content-Type,手动设置反而会丢失boundary,导致后端解析错误触发限制:
uploadFile(file: File, relativePath: string): Observable<HttpEvent<any>> { const formData = new FormData(); // 添加文件(键名可以自定义,后端不依赖键名的话随便写) formData.append('uploadFile', file, file.name); // 如果需要传递relativePath参数,直接追加到FormData里 formData.append('relativePath', relativePath); return this.http.post('/api/file/upload', formData, { reportProgress: true, // 开启进度监听(可选) observe: 'events' }); }
2. 避免把文件转成Base64
如果你自己写的代码里把文件转成了Base64字符串再上传,会大幅增加数据体积,很容易触发段长度限制,直接用File对象添加到FormData是最优解。
3. 对比第三方控件的请求结构
打开浏览器开发者工具(F12),分别查看第三方控件和你自己代码发送的请求:
- 检查
Content-Type是否为multipart/form-data; boundary=----WebKitFormBoundaryXXXX格式 - 查看请求体的结构,确保文件段的格式正确,没有额外的冗余内容
三、后端额外配置(可选)
如果以上两步都没问题,还是报错,可以尝试调整ASP.NET Core的表单选项,放宽Multipart相关限制:
在Program.cs中添加:
builder.Services.Configure<FormOptions>(options => { // 放宽整个多部分请求的总长度限制(按需设置,不要盲目设为MaxValue) options.MultipartBodyLengthLimit = 10L * 1024L * 1024L * 1024L; // 10GB // 放宽单个段的长度限制 options.MultipartHeadersLengthLimit = int.MaxValue; });
四、调试小技巧
用浏览器开发者工具或Fiddler抓包,对比第三方控件和你自己代码的请求差异,重点看:
- 请求头的
Content-Type是否包含正确的boundary - 请求体中文件段的大小是否超过16KB(如果超过,说明后端默认限制没被流式逻辑绕过,需要检查控制器实现)
内容的提问来源于stack exchange,提问作者Jonesie
相关产品推荐
相关产品推荐

