4

I create a zip file in a controller from a byte array and I return the zip file as a fileresult. When I download the zip File and extract the file, it is corrupt. I'm doing it this way:

byte[] fileBytes =array
MemoryStream fileStream = new MemoryStream(fileBytes);
MemoryStream outputStream = new MemoryStream();
fileStream.Seek(0, SeekOrigin.Begin);

using (ZipFile zipFile = new ZipFile())
{
    zipFile.AddEntry(returnFileName, fileStream);
    zipFile.Save(outputStream);
}

outputStream.Position = 0;

FileStreamResult fileResult = new FileStreamResult(outputStream, System.Net.Mime.MediaTypeNames.Application.Zip);
fileResult.FileDownloadName = returnFileName + ".zip";

return fileResult;
tereško
  • 58,060
  • 25
  • 98
  • 150
user1957868
  • 41
  • 1
  • 3
  • Does the downloaded file contain anything? – mortb Jan 08 '13 at 11:31
  • yes, contains the file, but when you open it is corrupted – user1957868 Jan 08 '13 at 12:17
  • the file is an xml file, and when i open it i get something like: K!‡Vá2Ž™[Content_Types].xml ¢( ¼•MOÂ@†ï&þ‡f¯†.`bŒ¡xðã¨$bâuítÃ~eg@ø÷n·XA!^ºi;ó¾ÏÎt§ƒë¥ÑÙ*gÖË»,[:©ì´`ÏãûÎ%Ë„•B;[²ëáéÉ. Instead of the original xmlf file – user1957868 Jan 09 '13 at 11:11
  • Should it not be a zip file when you open it? It should start with the letters PK if you open it in notepad. After PK there should be unreadable "nonsense" (which can be read when you unzip). The letters PK will indicate that it is a zip file. – mortb Jan 09 '13 at 11:17
  • ...and where is the code where you put the xml-file into the byte array? That may also be the place where it goes wrong? Please include it into your question. – mortb Jan 09 '13 at 11:34
  • Is a zip file, i mean i open it in notepad and has the pk. And i can unzip the file, correctly. But the content of the unzipped file looks like the thing that i put above instead of the original xml file. looks like after unzip(i do it with the windows), looks like the original zip or something like that. – user1957868 Jan 09 '13 at 11:38
  • well I'm saying that the contents of variable `fileBytes` may be wrong... – mortb Jan 09 '13 at 11:41
  • the content of the filebytes is correct, because there are two options to download, the file compressed or not. And if i download the file without compressing the file looks right. I mean the other option the return is return File(fileBytes, "text/html", returnFileName);. ANd this is correct so the filebytes is fine – user1957868 Jan 09 '13 at 11:48
  • I don't know why. But when I read the documentation I found an overload for zipFile.AddEntry that will accept a byte array (http://dotnetzip.herobo.com/DNZHelp/Index.html) I would try using that overload instead, then you don't have to worry about creating the first MemoryStream – mortb Jan 09 '13 at 12:25
  • yes,thats true.But the problem is the same – user1957868 Jan 09 '13 at 13:11
  • sorry, I don't know why you get the error... :( – mortb Jan 09 '13 at 13:13

2 Answers2

4

You might be unlucky hitting one of the open bugs in DotNetZip. There is e.g. an issue depending on the file size (https://dotnetzip.codeplex.com/workitem/14087).

Unfortunately, DotNetZip has some critical issues and the project seems no longer be actively be maintained. Better alternatives would be to use SharpZipLib (if you comply with their GPL-based license), or one of the .NET ports of zlib.

If you are on .NET 4.5 you can use the built-in classes in the System.IO.Compression namespace. The following sample can be found in the documentation of the ZipArchive class:

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var zipToOpen = 
                new FileStream(@"c:\tmp\release.zip", FileMode.Open))
            {
                using (var archive = 
                     new ZipArchive(zipToOpen, ZipArchiveMode.Update))
                {
                    var readmeEntry = archive.CreateEntry("Readme.txt");
                    using (var writer = new StreamWriter(readmeEntry.Open()))
                    {
                            writer.WriteLine("Information about this package.");
                            writer.WriteLine("========================");
                    }
                }
            }
        }
    }
}
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • Im not using 4.5,and i cant migrate.But anyway i dont think this is my case, because hat error will happen oonly with concrete files.but i have the problem with everyone – user1957868 Jan 09 '13 at 11:52
  • System.IO.Compression woot! – John Babb Feb 20 '17 at 15:57
  • It looks like this is fixed in the 'DotNetZip' branch which is available via Nuget: https://github.com/haf/DotNetZip.Semverd/pull/24 – Iain Apr 11 '19 at 08:12
0
public class HomeController : Controller
{
    public FileResult Index()
    {
        FileStreamResult fileResult = new FileStreamResult(GetZippedStream(), System.Net.Mime.MediaTypeNames.Application.Zip);
        fileResult.FileDownloadName = "result" + ".zip";
        return fileResult;
    }

    private static Stream GetZippedStream()
    {
        byte[] fileBytes = Encoding.ASCII.GetBytes("abc");
        string returnFileName = "something";

        MemoryStream fileStream = new MemoryStream(fileBytes);
        MemoryStream resultStream = new MemoryStream();

        using (ZipFile zipFile = new ZipFile())
        {
            zipFile.AddEntry(returnFileName, fileStream);
            zipFile.Save(resultStream);
        }

        resultStream.Position = 0;
        return resultStream;
    }
}
shamp00
  • 11,106
  • 4
  • 38
  • 81
  • On this way is creating a file that i dont want to and anyway the result is corrupted. have you tryed to open the file once is downloaded? And other thing my return type must be FileStreamResult because is a controller so i have to do something like FileStreamResult fileResult = new FileStreamResult(fileResultStream, System.Net.Mime.MediaTypeNames.Application.Zip); – user1957868 Jan 09 '13 at 11:02
  • Yes I can open the file. The contents are not corrupt. I've edited my answer to include the controller code. – shamp00 Jan 09 '13 at 12:19
  • fileBytes = Encoding.ASCII.GetBytes("abcdefghi"); if i overwrite the filebytes with this i get the result correctly. But with my files doesnt work. – user1957868 Jan 09 '13 at 13:50
  • Then it must be to do with the encoding of your byte array then. Can you convert it to a string with `Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), Encoding.UTF8, bytes);`? Does the string look correct? – shamp00 Jan 09 '13 at 14:58
  • I tryed that, but is still looking wrong when I open the file. – user1957868 Jan 11 '13 at 16:08
  • Can you post an example xml file including the code you are using to get it into a byte array? – shamp00 Jan 14 '13 at 13:02