PushStreamContent и ionic.zip

Мой метод webapi для архивирования на лету использует этот код

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;

я бы хотел

1) взять данные из _xmlRepository.GetInitialDataInXml

2) почтовые данные на лету через Ionic.Zip

3) вернуть сжатый поток как результат моего действия WebApi

Но на этой строчке zipEntry.Save(stream); процесс выполнения останавливается и не переходит на следующую строку. И метод ничего не возвращает

Так почему же он не возвращает мне файл?

2 ответа

Решение

Когда используешь PushStreamContentвам нужно будет close поток, чтобы сигнализировать, что вы закончили запись в поток.

Remarks раздел в документации:
http://msdn.microsoft.com/en-us/library/jj127066%28v=vs.118%29.aspx

Принятый ответ не верен. Нет необходимости закрывать поток, если вы хотите начать потоковую передачу. Потоковая передача начинается автоматически (диалог загрузки в браузере) после завершения делегированной функции. В случае больших файлов OutOfMemoryException генерируется, но обрабатывается и начинается потоковая передача -> HttResponseStream сбрасывается в сторону клиента.

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;
Другие вопросы по тегам