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); процесс выполнения останавливается и не переходит к следующей строке. И метод ничего не возвращает

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


person takayoshi    schedule 01.07.2014    source источник


Ответы (2)


При использовании PushStreamContent вам потребуется close поток, чтобы сообщить, что вы закончили запись в поток.

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

person Kiran Challa    schedule 01.07.2014

Принятый ответ неверен. Нет необходимости закрывать поток, если вы хотите начать потоковую передачу. Потоковая передача начинается автоматически (диалоговое окно загрузки в браузере), когда делегированная функция завершается. В случае больших файлов выдается исключение 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;
person Zoltan Tirinda    schedule 14.03.2017