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

基于ASP.NET Core MVC 2通过HTTP协议上传不超过1GB的二进制数据

解决ASP.NET Core MVC 2中HttpClient大二进制文件上传的内存问题

嘿,我注意到你当前的实现是把整个文件一次性读进内存再发送——这对于最大1GB的文件来说绝对是个隐患,很容易触发内存溢出(OOM),毕竟把这么大的数据全塞到内存里,客户端和服务器的内存压力都会拉满。下面给你优化后的方案,全程基于流操作,不用加载整个文件到内存:

客户端改进代码

直接用StreamContent包装FileStream,让HttpClient逐流发送数据,而非一次性加载整个文件:

var client = new HttpClient();
// 打开文件流,指定异步模式和合理的缓冲区大小
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true))
{
    var content = new StreamContent(fs);
    // 设置二进制内容类型
    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    
    // 发送POST请求,建议用异步方法避免阻塞
    var response = await client.PostAsync("https://你的服务器地址/api/upload", content);
    // 确保请求成功,失败会抛出异常
    response.EnsureSuccessStatusCode();
}

为什么这更好?

  • 无需把整个文件读成byte[],内存占用仅取决于缓冲区大小,而非文件总大小
  • StreamContent会自动处理ContentLength,不需要手动设置(你的原代码里这部分也没写完)
  • 异步操作更适合大文件传输,不会阻塞主线程

服务器端接收代码(ASP.NET Core MVC 2)

对应的,服务器端也要用流来接收,避免内存溢出:

[HttpPost("api/upload")]
public async Task<IActionResult> ReceiveBinaryFile()
{
    // 检查请求是否有内容
    if (!Request.ContentLength.HasValue || Request.ContentLength == 0)
    {
        return BadRequest("未检测到上传的二进制内容");
    }

    // 生成唯一文件名避免冲突,保存到指定目录
    var uploadDir = Path.Combine(Directory.GetCurrentDirectory(), "uploaded-files");
    Directory.CreateDirectory(uploadDir);
    var saveFileName = Guid.NewGuid().ToString();
    var savePath = Path.Combine(uploadDir, saveFileName);

    // 把请求体流直接复制到文件流,全程不加载到内存
    using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
    {
        await Request.Body.CopyToAsync(fileStream);
    }

    return Ok(new { Message = "文件上传成功", SavedFilePath = savePath });
}

关键配置:解除ASP.NET Core的请求大小限制

ASP.NET Core默认有请求大小限制,1GB的文件肯定会触发拦截,需要在Startup.cs的ConfigureServices里添加配置:

public void ConfigureServices(IServiceCollection services)
{
    // 配置表单请求大小限制(即使直接传流,也建议配置)
    services.Configure<FormOptions>(options =>
    {
        options.MultipartBodyLengthLimit = 1073741824; // 1GB,单位是字节
    });

    // 配置Kestrel服务器的请求大小限制
    services.Configure<KestrelServerOptions>(options =>
    {
        options.Limits.MaxRequestBodySize = 1073741824; // 1GB
    });

    // 其他原有配置...
    services.AddMvc();
}

额外注意事项

  • 缓冲区大小:建议用4096或8192字节,这是操作系统的常见页大小,性能最优
  • 错误处理:可以在客户端和服务器端添加try-catch块,处理网络中断、文件读写失败等异常
  • HttpClient复用:如果频繁上传文件,建议复用HttpClient实例,避免频繁创建销毁连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:53:28