简体   繁体   中英

PushStreamContent and ionic.zip

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?

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

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM