PushStreamContent and ionic.zip

1.6k Views Asked by At

My webapi method for zipping on the fly use this code

var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new PushStreamContent((stream, content, arg3) =>
                {
                    using (var zipEntry = new Ionic.Zip.ZipFile())
                    {
                        using (var ms = new MemoryStream())
                        {
                            _xmlRepository.GetInitialDataInXml(employee, ms);
                            zipEntry.AddEntry("content.xml", ms);
                            zipEntry.Save(stream); //process sleep on this line
                        }

                    }
                })
            };

            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = "FromPC.zip"
            };
            result.Content.Headers.ContentType =
                new MediaTypeHeaderValue("application/octet-stream");


            return result;

I want to

1) take data from _xmlRepository.GetInitialDataInXml

2) zip data on the fly via Ionic.Zip

3) return zipped stream as output of my WebApi action

But on this line zipEntry.Save(stream); execution process stops and don't go to next line. And method don't return anything

So why it doesnt' return me file?

2

There are 2 best solutions below

0
On BEST ANSWER

When using PushStreamContent, you would need to close the stream to signal that you are done writing to the stream.

Remarks section in the documentation:
http://msdn.microsoft.com/en-us/library/jj127066(v=vs.118).aspx

0
On

The accepted answer is not correct. It is not necessary to close the stream if you want to start streaming. The streaming starts automatically (download dialog in browser) when the delegated function ends. In case of big files OutOfMemoryException is thrown, but it is handled and the streaming begins -> HttResponseStream is flushed towards the client.

var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new PushStreamContent(async (outputStream, httpContext, transportContext) =>
{
    using (var zipStream = new ZipOutputStream(outputStream))
    {
        var employeeStream = _xmlRepository.GetEmployeeStream(); // PseudoCode
        zipStream.PutNextEntry("content.xml");
        await employeeStream.CopyToAsync(zipStream);
        outputStream.Flush();
    }
});

result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "FromPC.zip" };
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return result;