I'm trying to create a zip file that contains one or more files.
I'm using the .NET framework 4.5 and more specifically System.IO.Compression namespace.
The objective is to allow a user to download a zip file through a ASP.NET MVC application.
The zip file is being generated and sent to the client but when I try to open it by doing double click on it I get the following error:
Windows cannot open the folder. The compressed (zipped) folder ... is invalid.
Here's my code:
[HttpGet] public FileResult Download() { var fileOne = CreateFile(VegieType.POTATO); var fileTwo = CreateFile(VegieType.ONION); var fileThree = CreateFile(VegieType.CARROT); IEnumerable<FileContentResult> files = new List<FileContentResult>() { fileOne, fileTwo, fileThree }; var zip = CreateZip(files); return zip; } private FileContentResult CreateFile(VegieType vType) { string fileName = string.Empty; string fileContent = string.Empty; switch (vType) { case VegieType.BATATA: fileName = "batata.csv"; fileContent = "THIS,IS,A,POTATO"; break; case VegieType.CEBOLA: fileName = "cebola.csv"; fileContent = "THIS,IS,AN,ONION"; break; case VegieType.CENOURA: fileName = "cenoura.csv"; fileContent = "THIS,IS,A,CARROT"; break; default: break; } var fileBytes = Encoding.GetEncoding(1252).GetBytes(fileContent); return File(fileBytes, MediaTypeNames.Application.Octet, fileName); } private FileResult CreateZip(IEnumerable<FileContentResult> files) { byte[] retVal = null; if (files.Any()) { using (MemoryStream zipStream = new MemoryStream()) { using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, false)) { foreach (var f in files) { var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest); using (var entryStream = entry.Open()) { entryStream.Write(f.FileContents, 0, f.FileContents.Length); entryStream.Close(); } } zipStream.Position = 0; retVal = zipStream.ToArray(); } } } return File(retVal, MediaTypeNames.Application.Zip, "horta.zip"); }
Can anyone please shed some light on why is windows saying that my zip file is invalid when I double click on it.
A final consideration, I can open it using 7-Zip.
Your Zip file is invalid because of errors like virus infection, or an incomplete download from the internet. Both of these factors can cause a Zip file to become corrupt or damaged, thus leading to the error message, "The Compressed (zipped) folder is invalid".
You will see this error when the zip or postal code of your address does not match your purchasing card. Simply review what the postal or zip code of your purchasing card is, and re-enter the correct information to proceed.
Press and hold (or right-click) the file or folder, select (or point to) Send to, and then select Compressed (zipped) folder. A new zipped folder with the same name is created in the same location. To rename it, press and hold (or right-click) the folder, select Rename, and then type the new name.
You need to get the MemoryStream buffer via ToArray after the ZipArchive object gets disposed. Otherwise you end up with corrupted archive.
And please note that I have changed the parameters of ZipArchive constructor to keep it open when adding entries.
There is some checksumming going on when the ZipArchive is beeing disposed so if you read the MemoryStream before, it is still incomplete.
private FileResult CreateZip(IEnumerable<FileContentResult> files) { byte[] retVal = null; if (files.Any()) { using (MemoryStream zipStream = new MemoryStream()) { using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true)) { foreach (var f in files) { var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest); using (BinaryWriter writer = new BinaryWriter(entry.Open())) { writer.Write(f.FileContents, 0, f.FileContents.Length); writer.Close(); } } zipStream.Position = 0; } retVal = zipStream.ToArray(); } } return File(retVal, MediaTypeNames.Application.Zip, "horta.zip"); }
Just return the stream...
private ActionResult CreateZip(IEnumerable files) { if (files.Any()) { MemoryStream zipStream = new MemoryStream(); using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, false)) { foreach (var f in files) { var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest); using (var entryStream = entry.Open()) { entryStream.Write(f.FileContents, 0, f.FileContents.Length); entryStream.Close(); } } } zipStream.Position = 0; return File(zipStream, MediaTypeNames.Application.Zip, "horta.zip"); } return new EmptyResult(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With