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

.Net Core 2.1慢速网络下文件下载失败问题求助

问题描述

我用 .NET Core 2.1 写了一个 GET 方式的文件下载 REST API,正常网络环境下运行没问题,但在慢速网络区域的服务器上,用 Chrome 下载 20~25MB 的文件时,总会在 1~1.5 分钟内失败。我的代码如下:

[HttpGet("Download")]
public IActionResult Download(string filePath)
{
    byte[] fileData = null;
    System.IO.File.WriteAllBytes(filePath, datum);
    string fileName = $"File.zip";
    Response.ContentLength = fileData.LongLength;
    return File(fileData, "application/octet-stream", fileName);
}

我已经试过在 web.config 里加 requestTimeout="00:20:00",也在 API 里设置了 ContentLength,但都没用。想问下问题出在哪,该怎么解决?


问题原因分析

结合你的代码和场景,问题主要出在这几个方面:

  1. 文件操作逻辑错误:代码里写了 System.IO.File.WriteAllBytes(filePath, datum);,但你是要实现下载功能,这里是把datum写入文件而非读取文件到内存——虽然你说正常网络下能运行,大概率是输入代码时的笔误,但这个逻辑如果没修正,实际运行时要么报错要么返回空数据,肯定会影响下载流程。

  2. 全内存加载文件的弊端:你把整个文件读成 byte[] 再返回,2025MB的文件虽然不算超大,但在慢速网络下,服务器需要把内存中的完整数据持续发送11.5分钟,期间不仅占用服务器内存,还刚好触发了.NET Core 2.1 Kestrel服务器的默认请求超时(默认约100秒,和你遇到的失败时间完全吻合)。

  3. web.config配置未生效:.NET Core 2.1默认用Kestrel作为服务器,web.config里的requestTimeout是给IIS反向代理用的,直接对Kestrel服务器不生效,所以你修改后没有效果。


解决方案

针对这些问题,一步步来修复:

1. 修正代码中的文件操作错误

先把错误的写入逻辑改成读取文件的正确代码(如果这是笔误的话):

byte[] fileData = System.IO.File.ReadAllBytes(filePath);

不过更推荐下面的流式传输方案,避免全内存加载的问题。

2. 改用流式传输(核心解决办法)

不要把整个文件加载到内存,而是用FileStream流式返回,这样内存占用极低,Kestrel会逐块发送数据,更适配慢速网络的长传输场景。修改后的代码如下:

[HttpGet("Download")]
public IActionResult Download(string filePath)
{
    // 先判断文件是否存在,避免抛出异常
    if (!System.IO.File.Exists(filePath))
    {
        return NotFound("请求的文件不存在");
    }

    string fileName = $"File.zip";
    // 打开文件流,指定异步读取、共享读取权限,缓冲区设为4096字节(通用最优值)
    var fileStream = new System.IO.FileStream(
        filePath, 
        System.IO.FileMode.Open, 
        System.IO.FileAccess.Read, 
        System.IO.FileShare.Read, 
        bufferSize: 4096, 
        useAsync: true);

    // 直接返回文件流,框架会自动处理ContentLength和分块传输逻辑
    return File(fileStream, "application/octet-stream", fileName);
}

3. 配置Kestrel的超时参数

因为.NET Core 2.1的Kestrel默认请求超时是100秒,刚好是你遇到的失败时间,所以需要在Program.cs里增加Kestrel的超时配置:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel(options =>
        {
            // 设置连接保持超时,适配长传输场景
            options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(20);
            // 设置整个请求的超时时间
            options.Limits.RequestTimeout = TimeSpan.FromMinutes(20);
        });

4. (可选)检查客户端Chrome的下载设置

如果还是出现下载失败,可以检查Chrome的下载超时:在Chrome地址栏输入chrome://flags/#download-timeout,把超时时间调长一点(默认可能是几分钟),避免客户端主动中断连接。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:15:44