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

ASP.NET Core Web API多文件Zip下载显示二进制数据问题求助

ASP.NET Core Web API Zip下载二进制解析错误解决方法

问题场景

在ASP.NET Core Web API中使用System.IO.Compression将多个文件打包为Zip提供下载时,前端出现二进制文本解析错误,错误信息如下:

Error from backend. {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost:4000/api/filegeneration/createfile/2023-02-08/1","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost:4000/api/filegeneration/createfile/2023-02-08/1","error":{"error":{},"text":"PK\u0003\u0004\u0014\u0000\u0000\u0000\b\u0000��HV�<br />
u0010\u0001\u000b\u0000\u0000\u0000\u0003\u0000\u0000\u0000\u001e\u0000\u0000\u0000
Fareshare_Qty_08.02.2023_0.txtz�{?\u0000\u0000\u0000��\u0003\u0000PK\u0001\u0002\u0014
\u0000\u0014\u0000\u0000\u0000\b\u0000��HV�\u0010\u0001\u000b\u0000\u0000\u0000\u0003\u0000\u0000
\u0000\u001e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Fareshare_Qty_08.02.2023_0.txtPK\u0005
\u0006\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000L\u0000\u0000\u0000G\u0000\u0000\u0000\u0000\u0000"}}

控制器代码:

using (var outstream = new MemoryStream())
{
    using (var archive = new ZipArchive(outstream, ZipArchiveMode.Create, true))
    {
        foreach (string filePath in files)
        {
            var filearcive = archive.CreateEntry(Path.GetFileName(filePath), CompressionLevel.Optimal);
            using (var entrystream = filearcive.Open())
            {
                using (var fileCompressionStream = new MemoryStream(System.IO.File.ReadAllBytes(filePath)))
                {
                    await fileCompressionStream.CopyToAsync(entrystream);
                }
            }
        }
    }
    outstream.Position = 0;
    return File(outstream.ToArray(), "application/zip", "Fareshare.zip");
}

解决步骤

1. 修复后端响应内容污染

从错误信息的text字段可见,Zip二进制流中混入了<br />标签,说明后端响应存在额外HTML输出,导致Zip文件损坏:

  • 给控制器方法添加异常捕获,避免异常处理中间件输出HTML错误内容:
    try
    {
        using (var outstream = new MemoryStream())
        {
            using (var archive = new ZipArchive(outstream, ZipArchiveMode.Create, true))
            {
                foreach (string filePath in files)
                {
                    var entry = archive.CreateEntry(Path.GetFileName(filePath), CompressionLevel.Optimal);
                    using (var entryStream = entry.Open())
                    using (var fileCompressionStream = new MemoryStream(System.IO.File.ReadAllBytes(filePath)))
                    {
                        await fileCompressionStream.CopyToAsync(entryStream);
                    }
                }
            }
            outstream.Position = 0;
            return File(outstream.ToArray(), "application/zip", "Fareshare.zip");
        }
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, $"打包文件失败:{ex.Message}");
    }
    
  • 检查全局中间件(如异常处理、日志中间件),确保不会在正常响应中添加额外HTML内容。

2. 前端调整响应处理逻辑

前端默认将响应解析为JSON,但实际返回的是二进制Zip流,需指定responseType为blob并处理文件下载:
以Angular为例:

import { HttpClient } from '@angular/common/http';

// ...

constructor(private http: HttpClient) {}

downloadZip() {
  const url = 'http://localhost:4000/api/filegeneration/createfile/2023-02-08/1';
  this.http.get(url, { responseType: 'blob' }).subscribe(blob => {
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = 'Fareshare.zip';
    document.body.appendChild(link);
    link.click();
    // 清理资源
    window.URL.revokeObjectURL(downloadUrl);
    document.body.removeChild(link);
  }, error => {
    console.error('下载失败:', error);
  });
}

3. 后端代码性能优化(可选)

原代码使用File.ReadAllBytes会将整个文件加载到内存,大文件场景可改为流式读取优化内存占用:

using (var outstream = new MemoryStream())
{
    using (var archive = new ZipArchive(outstream, ZipArchiveMode.Create, true))
    {
        foreach (string filePath in files)
        {
            var entry = archive.CreateEntry(Path.GetFileName(filePath), CompressionLevel.Optimal);
            using (var entryStream = entry.Open())
            using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                await fileStream.CopyToAsync(entryStream);
            }
        }
    }
    outstream.Position = 0;
    return File(outstream.ToArray(), "application/zip", "Fareshare.zip");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:13:59