2009-03-06 4 views
3

Моя проблема: когда пользователь нажимает кнопку изображения на странице aspx, codebehind создает zip-файл, а затем я пытаюсь передать этот zip-файл пользователю.Как вы делаете поток zip-файла одним нажатием кнопки изображения в asp.net?

Для воспроизведения файла я использую следующий код:

FileInfo toDownload = new FileInfo(fullFileName); 
if (toDownload.Exists) 
{ 
    Response.Clear(); 
    Response.ContentType = "application/zip"; 
    Response.AppendHeader("Content-Disposition", "attachment;filename=" + 
      toDownload.Name); 
    Response.AppendHeader("Content-Length", toDownload.Length.ToString()); 
    Response.TransmitFile(fullFileName); 
    HttpContext.Current.ApplicationInstance.CompleteRequest(); 
} 

Когда я пытаюсь выполнить это я получаю следующее сообщение об ошибке на странице:

Sys.WebForms.PageRequestManagerParserErrorException: Сообщение, полученное с сервера, не может быть проанализировано. Общими причинами этой ошибки являются изменение ответа на вызовы Response.Write(), фильтры ответов, HttpModules или трассировка сервера. Подробнее: Ошибка разбора возле «PK ...».

PK - первые два символа в zip-файле, которые идентифицируют его как zip-файл, поэтому я знаю, что он пытается отправить zip-файл в браузер. Тем не менее, создается впечатление, что браузер пытается интерпретировать и/или отображать zip-файл, пока я хочу, чтобы он отображал параметр файла загрузки.

Идеи?

EDIT: Here's a link to a post from the guy who wrote the above error message.

+0

Какой код работает до этого? Как правило, это происходит потому, что вы уже отправили заголовки браузера. –

ответ

2

Например, вот как я отправить PDF клиенту в одном из моих приложений (вы должны заполнить/изменить некоторые из недостающих объявлений переменных):

 byte[] rendered = uxReportViewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings); 

     Response.Buffer = true; 
     Response.Clear(); 
     Response.ClearHeaders(); 
     Response.ContentType = mimeType; 
     Response.CacheControl = "public"; 
     Response.AddHeader("Pragma", "public"); 
     Response.AddHeader("Expires", "0"); 
     Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 
     Response.AddHeader("Content-Description", "Report Export"); 
     Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "." + extension + "\""); 

     Response.BinaryWrite(rendered); 
     Response.Flush(); 
     Response.End(); 

Вы изменили бы тип контента и конвертировали бы свой zip-файл в массив байтов, а затем, я думаю, вы можете заполнить остальные.

+0

Спасибо за идею larsonic - я пробовал это, но, к сожалению, это не решает проблему. Как я уже говорил, я думаю, что это что-то в браузере ... – Guy

0

Парень, разве вы не используете DotNetZip для генерации zip-файлов? Что делать, если вы не создали zip-файл на диске, а только в памяти? Этот пример использует DotNetZip для этого.

Response.Clear(); 
    Response.BufferOutput = false; 
    String ReadmeText= "This is content that will appear in a file " + 
         "called Readme.txt.\n" + 
         System.DateTime.Now.ToString("G") ; 
    string archiveName= String.Format("archive-{0}.zip", 
             DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
    Response.ContentType = "application/zip"; 
    Response.AddHeader("content-disposition", "attachment; filename=" + archiveName); 

    using (ZipFile zip = new ZipFile()) 
    { 
     // add an entry from a string: 
     zip.AddEntry("Readme.txt", "", ReadmeText); 
     zip.AddFiles(filesToInclude, "files"); 
     zip.Save(Response.OutputStream); 
    } 
    // Response.End(); // no - see http://stackoverflow.com/questions/1087777 
    HttpContext.Current.ApplicationInstance.CompleteRequest(); 
+0

Cheeso - я использую DotNetZip за вашу рекомендацию в другом потоке, но я не думаю, что это проблема. Я думаю, что это что-то происходит в браузере. – Guy

1

я, наконец, решить эту проблему, а также заметил, что, возможно, я не дал достаточно информации в вопросе: Кнопка изображения находится внутри UpdatePanel.

Решение было создать PostBackTrigger для управления:

<Triggers> 
    <asp:PostBackTrigger ControlID="ibDownload" /> 
</Triggers>