views:

1043

answers:

3

My problem: When a user clicks an image button on an aspx page the codebehind creates a zip file and then I attempt to stream that zip file to the user.

To stream the file I'm using the following code:

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();
}

When I try to execute this I'm getting the following error on the page:

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled. Details: Error parsing near 'PK...'.

The PK are the first two characters in a zip file that identify it as a zip file so I know that it's attempting to send the zip file to the browser. However, I get the impression that the browser is trying to interpret and/or render the zip file while I want it to pop-up a download file option.

Ideas?

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

+1  A: 

For example, here's how I send a PDF to the client in one of my apps (you'll have to fill in/change some of the missing variable declarations):

        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();

You'd change the content type, and convert your zip file to a byte array, and then I think you can fill in the rest.

Cory Larson
Thanks for the idea larsonic - I tried that but unfortunately that doesn't solve the problem. As I mentioned, I think that it's something in the browser...
Guy
A: 

Guy, aren't you using DotNetZip to generate the zip files? What if you didn't create the zip file on disk but only in memory? This example uses DotNetZip to do that.

    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();
Cheeso
Cheeso - I am using DotNetZip per your recommendation in another thread but I don't think that this is the problem. I think that it's something happening on the browser.
Guy
A: 

I finally solved the problem and also noticed that perhaps I didn't give enough information in the question: The image button is inside an UpdatePanel.

The solution was to create a PostBackTrigger for the control:

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