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

.NET中如何设置Multipart分段上传的文件最大体积限制

为什么FormOptions配置不生效

FormOptions的MultipartBodyLengthLimit限制仅作用于ASP.NET Core自带的表单解析流程,也就是你用Request.Form、IFormFile接收上传内容时才会触发校验。你现在直接用MultipartReader读取原始请求Body,完全绕开了框架自带的表单解析逻辑,所以这个配置自然不会生效。

不需要把流全读入内存就能校验大小

你可以在读取流写入目标存储(磁盘/对象存储等)的过程中实时统计已读取的字节数,超过对应上限就直接终止操作即可,全程不会把整个文件加载到内存。

具体实现方案

首先定义扩展名和大小限制的映射规则,示例如下:

// 单位:字节,规则可自行调整
private readonly Dictionary<string, long> _sizeLimitPerExtension = new(StringComparer.OrdinalIgnoreCase)
{
    { ".pdf", 5 * 1024 * 1024 }, // PDF最大5MB
    { ".jpg", 2 * 1024 * 1024 }, // JPG图片最大2MB
    { ".txt", 1 * 1024 * 1024 }  // 文本文件最大1MB
};
// 未匹配到扩展名的默认最大限制
private const long DefaultSizeLimit = 3 * 1024 * 1024;

然后改造你的上传接口逻辑,增加流式大小校验:

[HttpPost]
public async Task<IActionResult> Post()
{
    var request = HttpContext.Request;

    // 原有ContentType校验逻辑保留
    if (!request.HasFormContentType ||
        !MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
        string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
    {
        return new UnsupportedMediaTypeResult();
    }

    var reader = new MultipartReader(mediaTypeHeader.Boundary.Value, request.Body);
    var section = await reader.ReadNextSectionAsync();

    while (section != null)
    {
        var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
            out var contentDisposition);

        if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
            !string.IsNullOrEmpty(contentDisposition.FileName.Value))
        {
            var fileName = contentDisposition.FileName.Value;
            var extension = Path.GetExtension(fileName);
            
            // 获取对应扩展名的大小限制
            if (!_sizeLimitPerExtension.TryGetValue(extension, out var maxSize))
            {
                maxSize = DefaultSizeLimit;
            }

            long totalRead = 0;
            var buffer = new byte[4096];
            // 替换为你实际要写入的目标流,比如本地文件流、对象存储上传流等
            var targetStream = new MemoryStream(); 
            int read;
            // 边读边统计字节数
            while ((read = await section.Body.ReadAsync(buffer)) > 0)
            {
                totalRead += read;
                if (totalRead > maxSize)
                {
                    return BadRequest($"文件大小超过限制,{extension}格式文件最大允许{maxSize/1024/1024}MB");
                }
                await targetStream.WriteAsync(buffer.AsMemory(0, read));
            }

            // 校验通过后执行上传逻辑
            await _uploader.UploadAsync(targetStream);
            return Ok();
        }

        section = await reader.ReadNextSectionAsync();
    }

    return BadRequest("No files data in the request.");
}

额外注意点

如果你使用了IIS、Nginx等反向代理服务,还需要同步修改反向代理层的上传大小限制:

  • IIS需要在web.config中配置maxAllowedContentLength参数
  • Nginx需要配置client_max_body_size参数
    否则请求还没到达.NET服务就会被反向代理拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:36:06