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

.NET Core 7 MVC生成Zip文件供前端下载失败问题解决

解决.NET Core 7 MVC中Fetch下载Zip包损坏的问题

在.NET Core 7 MVC项目中实现接口,前端通过Fetch调用该接口后,服务器将文件压缩为Zip包返回供下载,但下载后的Zip文件无法打开,WinRAR提示“存档格式未知或已损坏”。经测试,Zip文件生成逻辑在控制台应用中可正常生成有效文件,问题出在文件传输或接收环节,以下是问题排查及修复后的完整代码:

初始代码

后端C#代码

[HttpGet]
public HttpResponseMessage DownloadPDFs(string jobId)
{
    var selectedFiles = _requestsManager.GetPDFsZipFromJobId(jobId);

    using var memoryStream = new MemoryStream();

    using var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true);

    foreach (var pdfFile in selectedFiles)
    {
        if (pdfFile != string.Empty)
        {
            var entry = archive.CreateEntry(Path.GetFileName(pdfFile));

            using var entryStream = entry.Open();
            using var pdfFileStream = System.IO.File.OpenRead(pdfFile);

            pdfFileStream.CopyTo(entryStream);
        }
    }
    //UPDATE 1
    archive.Dispose();
    //
    memoryStream.Seek(0, SeekOrigin.Begin);

    var response = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new StreamContent(memoryStream)
    };

    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = $"{jobId}_PDFs.zip"
    };

    return response;
}

前端JavaScript代码

function handlePDFsBatch() {
    fetch("/Engine/DownloadPDFs")
        .then((response) => {
            if (response.status === 200) return response.blob();
            else if (response.status === 404) throw new Error("File not found.");
            else throw new Error("Unexpected error.");
        })
        .then((blob) => {
            const url = window.URL.createObjectURL(blob);

            const a = document.createElement("a");
            a.style.display = "none";
            a.href = url;
            a.download = `${crntJobId}.zip`;
            document.body.appendChild(a);

            a.click();
            window.URL.revokeObjectURL(url);
        })
        .catch((error) => {
            console.error("Error downloading file:", error);
        });
}

排查说明

Zip文件生成逻辑在控制台应用中可正常生成有效文件,排除压缩逻辑问题,确定问题出在文件传输或接收环节。

修复后代码

后端C#代码

将返回类型从HttpResponseMessage改为IActionResult,使用ASP.NET Core内置的File方法返回流,确保响应头和流处理正确:

public MemoryStream GetZipStream(List<string> files)
{
    var memoryStream = new MemoryStream();

    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
    {

        foreach (var pdfFile in files)
        {
            if (pdfFile != string.Empty)
            {
                var entry = archive.CreateEntry(Path.GetFileName(pdfFile));

                using var entryStream = entry.Open();
                using var pdfFileStream = System.IO.File.OpenRead(pdfFile);

                pdfFileStream.CopyTo(entryStream);
            }
        }
    }

    return memoryStream;
}

[HttpGet]
public IActionResult DownloadPDFs(string jobId)
{
     var selectedFiles = _requestsManager.GetPDFsNamesFromJobId(jobId);

     var memoryStream = _requestsManager.GetZipStream(selectedFiles);

     memoryStream.Seek(0, SeekOrigin.Begin);

     return File(memoryStream, "application/zip", $"{jobId}_PDFs.zip");
}

前端JavaScript代码

优化响应判断逻辑,拆分下载逻辑为独立函数:

fetch("/Engine/DownloadPDFs")
    .then((response) => {
        if (response.ok) return response.blob();
        else throw new Error('Failed to fetch the file');
    })
    .then(blob => startDownload(blob))
    .catch((error) => {
        console.error("Error downloading file:", error);
    });

function startDownload(blob) {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'PDFs.zip';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:47:50