使用ASP.Net Core和Angular 6构建损坏的zip文件

时间:2018-08-08 07:16:48

标签: c# angular asp.net-core .net-core zip

我使用的是Angular 6和ASP.Net内核,我有一个Web API,在其中构建了一个归档文件(zip),该文件将恢复为angular,并开始下载操作。

我面临两个问题:

  • 第一个是,只能使用压缩软件(例如7zip)提取存档,而不能通过Windows 10功能对其进行访问:

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

我机器上的其他zip文件运行正常。

  • 第二个问题是,如果我返回字节数组,我的代码可以工作,但是当我返回memoryStream时,我的代码不起作用(在第二种情况下,我会遇到一些CORS错误)

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

在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

1 个答案:

答案 0 :(得分:0)

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

ZipArchive gives Unexpected end of data corrupted error

基本上,我不得不将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();
}

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