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

解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:17:19