首页 > 解决方案 > 使用 ASP.Net 核心和 Angular 6 构建损坏的 zip 文件

问题描述

我正在使用 Angular 6 和 ASP.Net 核心,我有一个 web api,我在其中构建了一个存档 (zip) 文件,我返回到 angular,然后开始下载操作。

我面临两个问题:

错误消息:“windows 无法打开文件夹。压缩(压缩)文件夹 'xx' 无效”

我机器上的其他 zip 文件工作得很好。

这是我使用的代码的一些部分(我只会发布代码的一些相关部分):

在 Angular (6) 中,我这样发布:

this.post<T>(url, content,
   {
       headers: new HttpHeaders({ 'Accept': 'application/x-zip-compressed', 
                'Content-Type': 'application/json' }),
       observe: 'body',
       responseType: 'blob'
   }
)

在 ASP.NET 核心 API 中:

// In the Controller
// init some variables and stuff..
var fileName...
var paths..  // a list of paths to my files

new FileExtensionContentTypeProvider().TryGetContentType(fileName, out contentType);
return File(FileService.ZipFiles(paths).ToArray(), contentType, fileName);
// here, note that contentType would be 'application/x-zip-compressed'. also note the ToArray()

在文件服务中,我执行以下操作:

using (var zipMemoryStream = new MemoryStream())
{
    var zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create);
    foreach (var path in filePaths)
    {
        // some checks on file existance here..


        ZipArchiveEntry entry = zipArchive.CreateEntry(Path.GetFileName(path));
        using (var entryStream = entry.Open())
        using (var fileStream = File.Open(path, FileMode.Open, FileAccess.Read))
        {
            fileStream.CopyTo(entryStream);
        }
    }

    zipMemoryStream.Position = 0;

    // here i return the memory stream, but i have to convert it to a byte 
    // array in the return of the controller above for it to work
    return zipMemoryStream;
}

编辑:

使用 7zip 分析文件时,它显示为错误:

unexpected end of data

标签: c#angularasp.net-core.net-corezip

解决方案


使用此 SO 问题中提供的答案解决:

ZipArchive 给出意外结束的数据损坏错误

基本上,我不得不将 FileService 代码的一部分(我在问题中提供)更改为:

using (var zipMemoryStream = new MemoryStream())
{
    //  --> put the zip archive in a using block
    using(var zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create))
    {
        foreach (var path in filePaths)
        {
            // some checks on file existance here..


            ZipArchiveEntry entry = zipArchive.CreateEntry(Path.GetFileName(path));
            using (var entryStream = entry.Open())
            using (var fileStream = File.Open(path, FileMode.Open, FileAccess.Read))
            {
                fileStream.CopyTo(entryStream);
            }
        }
    }

    // --> return a byte array AFTER the using block of the zipArchive
    return zipMemoryStream.ToArray();
}

(我使用 // --> 来显示代码的编辑部分)


推荐阅读