Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Core ZipArchive Is Invalid

I'm creating a zip file in a Web API call under MVC Core, but Windows can't open the resulting file, claiming it's invalid.

Here's the code for creating the archive:

ZipArchive archive = new ZipArchive( archiveMS, ZipArchiveMode.Create, true );

// loop over a series of Azure blobs which contain text
foreach( BlobPathInfo curBPI in model.Paths )
{
    // AzureBlobFile is a wrapper for CloudBlockBlob
    AzureBlobFile blobFile = blobFolder.File( curBPI.BlobPath.FileName );
    Stream blobStream = blobFile.OpenRead();

    ZipArchiveEntry entry = archive.CreateEntry( zipFolderPath.ToString() );

    using( Stream zipStream = entry.Open() )
    {
        blobStream.CopyTo( zipStream );
    }
}

archive.Dispose();
archiveMS.Seek( 0, SeekOrigin.Begin );

return new FileStreamResult( archiveMS, "application/zip" );

This WebAPI method is called from an angular script and converted to a client-side blob linked to an element:

// downloadFiles does a POST request and returns a promise
downloadFiles( params )
.then( function( success ) {
    var linkElement = document.createElement( 'a' );
    var blob = new Blob( [success.data], { type: 'application/zip' } );
    var url = window.URL.createObjectURL( blob );

    linkElement.setAttribute( 'href', url );
    linkElement.setAttribute( 'download', fileName );

    var clickEvent = new MouseEvent( 'click',
    {
        view: window,
        bubbles: true,
        cancelable: false
    } );

    linkElement.dispatchEvent( clickEvent );

This all works in that the archive is created on the server, downloaded to the client, and then saved through the file save dialog. But the resulting archive on disk is invalid so far as Windows is concerned.

The Windows error message is not helpful, basically just declaring that the file is invalid. But I did notice two other things that may be significant:

1) If I don't create an entry in the zip archive on the server -- if I just create the archive and download that -- it opens up correctly under Windows (and, of course, shows that it has no content/entries).

2) In checking the error logs I noticed the following:

Log Name: Application Source: IIS Express Date:
1/31/2017 4:20:15 PM Event ID: 2264 Task Category: None Level:
Warning Keywords: Classic User: N/A Computer:
Muddlehead Description: The directory specified for caching compressed content C:\Users\Mark\AppData\Local\Temp\iisexpress\IIS Temporary Compressed Files\Clr4IntegratedAppPool is invalid. Static compression is being disabled. Event Xml:
2264 3 0 0x80000000000000 90672 Application Muddlehead C:\Users\Mark\AppData\Local\Temp\iisexpress\IIS Temporary Compressed Files\Clr4IntegratedAppPool 03000000

Thoughts on how to fix this?

like image 475
Mark Olbert Avatar asked Feb 01 '17 00:02

Mark Olbert


1 Answers

You should write 'using' when work with ZipArchive. When IDisposible run it complete your file correctly.

byte [] zipBytes;
using (MemoryStream ms = new MemoryStream())
{
    var file1 = Encoding.ASCII.GetBytes("Hello,world!");
    using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        var zipArchiveEntry = archive.CreateEntry("file1.txt",     CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) 
          { zipStream.Write(file1, 0, file1.Length); }

    }
    zipBytes = ms.ToArray(); // good place to assign
}
return File(zipBytes, "application/zip", "Archive.zip");

You get bad zip when write as this

byte [] zipBytes;
using (MemoryStream ms = new MemoryStream())
{
    var file1 = Encoding.ASCII.GetBytes("Hello,world!");
    using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        var zipArchiveEntry = archive.CreateEntry("file1.txt",     CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) 
        {
           zipStream.Write(file1, 0, file1.Length);
        }
        zipBytes = ms.ToArray(); //bad place to assign
    }

}
return File(zipBytes, "application/zip", "Archive.zip");
like image 113
Костя Гришин Avatar answered Nov 16 '22 14:11

Костя Гришин