如何从asp.net中单击图像按钮来流压缩文件?

时间:2023-01-24 14:53:16

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.

我的问题是:当用户单击aspx页面上的图像按钮时,后面的代码创建一个zip文件,然后我尝试将该zip文件流到用户。

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...'.

Sys.WebForms。PageRequestManagerParserErrorException:无法解析从服务器接收的消息。这种错误的常见原因是,响应通过调用response . write()、响应过滤器、httpmodule或服务器跟踪进行修改。细节:在“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.

PK是zip文件中的前两个字符,它们将其标识为zip文件,因此我知道它正在尝试将zip文件发送到浏览器。但是,我得到的印象是浏览器试图解释和/或呈现zip文件,而我希望它弹出一个下载文件选项。

Ideas?

想法吗?

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

编辑:这里有一个链接指向一个写了上面错误信息的人的帖子。

3 个解决方案

#1


2  

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):

例如,以下是我如何在我的一个应用程序中向客户发送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();

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.

您将更改内容类型,并将zip文件转换为字节数组,然后我认为您可以填充其余的内容。

#2


1  

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.

我最终解决了这个问题,并注意到在这个问题中可能没有提供足够的信息:图像按钮在UpdatePanel中。

The solution was to create a PostBackTrigger for the control:

解决方案是为控件创建一个PostBackTrigger:

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

#3


0  

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.

伙计,你不是在用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://*.com/questions/1087777
    HttpContext.Current.ApplicationInstance.CompleteRequest();

#1


2  

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):

例如,以下是我如何在我的一个应用程序中向客户发送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();

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.

您将更改内容类型,并将zip文件转换为字节数组,然后我认为您可以填充其余的内容。

#2


1  

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.

我最终解决了这个问题,并注意到在这个问题中可能没有提供足够的信息:图像按钮在UpdatePanel中。

The solution was to create a PostBackTrigger for the control:

解决方案是为控件创建一个PostBackTrigger:

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

#3


0  

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.

伙计,你不是在用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://*.com/questions/1087777
    HttpContext.Current.ApplicationInstance.CompleteRequest();