.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
相关产品推荐
相关产品推荐

