0

I'm failing to generate a zip file within a web api controller. I need to generate a zip file when the method is called that can be downloaded. The zip file is purely for downloading. The zip file should not exist on the server. The contents of the zip file is an array of pdf files that exist on the server. I've attempted the following but I'm not sure how to populate the HttpResponseMessage Content object correctly.

Can anyone suggest how this is done please?

Thank you

My failing attempt

using (FileStream zipFile = new FileStream("??", FileMode.Create))
{
    using (ZipArchive archive = new ZipArchive((zipFile, ZipArchiveMode.Create))
    {
        foreach (var pFile in listOfPdfFilenames)
        {
            var filePath = _pdfPathProvider.GetFullPath(pFile);

            if (File.Exists(filePath))
            {
                archive.CreateEntryFromFile(filePath, filePath);
            }
        }

        var result = new HttpResponseMessage(HttpStatusCode.OK);

        // Not sure how to populate the content object with my zipped file
        result.Content = new Content(..);  // Or ByteArrayContent(..)

        return result;
    }

Having looked at the example provided in question #45172328 I get the "zip file is empty". I've provided an example below after this change.

Second attempt

var model = new List<FileModel>();

foreach (var pFile in listOfPdfFilenames)
{
    var filePath = _pdfPathProvider.GetFullPath(pFile);

    if (File.Exists(filePath))
    {
        using (FileStream stream = File.Open(filePath, FileMode.Open))
        {
            model.Add(new FileModel
            {
                FileName = filePath,
                FileContent = ReadToEnd(stream)
            });                    
        }

        var archiveStream = model.Compress();
        var content = new StreamContent(archiveStream);
        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = content;
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "fileexport.zip"
        };

        return response;

Implementation for ReadToEnd method

    public static byte[] ReadToEnd(System.IO.Stream stream)
    {
        long originalPosition = 0;

        if (stream.CanSeek)
        {
            originalPosition = stream.Position;
            stream.Position = 0;
        }

        try
        {
            byte[] readBuffer = new byte[4096];

            int totalBytesRead = 0;
            int bytesRead;

            while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
            {
                totalBytesRead += bytesRead;

                if (totalBytesRead == readBuffer.Length)
                {
                    int nextByte = stream.ReadByte();
                    if (nextByte != -1)
                    {
                        byte[] temp = new byte[readBuffer.Length * 2];
                        Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                        Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                        readBuffer = temp;
                        totalBytesRead++;
                    }
                }
            }

            byte[] buffer = readBuffer;
            if (readBuffer.Length != totalBytesRead)
            {
                buffer = new byte[totalBytesRead];
                Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
            }
            return buffer;
        }
        finally
        {
            if (stream.CanSeek)
            {
                stream.Position = originalPosition;
            }
        }
    }

Empty zip file message

error message received when opening the zip file

Martin
  • 35
  • 3
  • Thanks for finding that - I've tried the example source code provided in that example but it says the zip file is empty. I've provided an update to the question – Martin Jan 16 '18 at 12:17
  • Also I would like to add that as a new member of stack overflow I cannot add a comment to the "duplicate question" as I need 50 credits. Therefore I would have no way to ask my question without creating this new question. – Martin Jan 17 '18 at 17:15

0 Answers0