You need to enable JavaScript to run this app. ASP.NET Core控制器实现Blazor端下载wwwroot下zip文件问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core控制器实现Blazor端下载wwwroot下zip文件问题咨询

问题原因

  1. ASP.NET Core控制器中错误使用HttpResponseMessage作为返回值,Ok()方法会将该对象序列化为JSON返回,而非你预期的文件流,导致前端收到的是JSON数据,无法触发下载。
  2. Blazor端调用GetAsync后仅拿到响应结果,未主动处理响应触发浏览器下载行为。
  3. 原有Blazor调用代码存在语法错误,参数拼接缺少左大括号。

控制器代码修正

ASP.NET Core的ControllerBase内置了File()方法可直接返回文件结果,无需手动构造响应对象,框架会自动处理所有下载所需的响应头:

[HttpGet("DownloadOutput")]
public IActionResult Invoice(string JobId)
{
    // 校验入参合法性,防止路径遍历攻击
    if (string.IsNullOrWhiteSpace(JobId))
        return BadRequest("JobId不能为空");

    // 建议用Path.Combine拼接路径,兼容不同操作系统
    var searchPath = Path.Combine("***PATH***", JobId);
    string file = Directory.EnumerateFiles(searchPath, "*.*", SearchOption.AllDirectories)
        .Where(n => Path.GetExtension(n).Equals(".zip", StringComparison.OrdinalIgnoreCase))
        .FirstOrDefault();

    if (string.IsNullOrEmpty(file) || !System.IO.File.Exists(file))
        return NotFound("目标压缩包不存在");

    // 仅取文件名,不要返回服务器端完整路径
    var fileName = Path.GetFileName(file);
    // 大文件建议直接返回文件流,避免ReadAllBytes占用过多内存
    // return File(new FileStream(file, FileMode.Open, FileAccess.Read), "application/octet-stream", fileName);
    return File(System.IO.File.ReadAllBytes(file), "application/octet-stream", fileName);
}

Blazor端代码修正

方案1:直接触发浏览器原生下载(无鉴权场景推荐)

不需要调用GetAsync,直接通过JS动态创建a标签触发下载即可:

// 注入IJSRuntime后调用
var downloadUrl = $"Inventer/DownloadOutput?jobId={JobId}";
await JSRuntime.InvokeVoidAsync(@"
    (url) => {
        const a = document.createElement('a');
        a.href = url;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }
", downloadUrl);

方案2:处理GetAsync响应(需要携带自定义请求头/鉴权场景使用)

var result = await Http.GetAsync($"Inventer/DownloadOutput?jobId={JobId}");
if (result.IsSuccessStatusCode)
{
    var blobBytes = await result.Content.ReadAsByteArrayAsync();
    await JSRuntime.InvokeVoidAsync(@"
        (data, fileName) => {
            const blob = new Blob([data], { type: 'application/octet-stream' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    ", blobBytes, "下载文件.zip");
}

注意事项

  • 务必对JobId做合法性校验,禁止出现../等路径跳转字符,避免攻击者遍历服务器敏感文件
  • 超过100M的大文件不要使用ReadAllBytes,直接返回文件流即可,避免服务端内存溢出
  • 如果站点配置了跨域规则,需要允许下载接口的跨域访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 09:54:03