1

我们有一个网页,它从一个 url 中获取一系列字符串,找到一些与这些字符串相关联的 pdf,使用DotNetZip将它们压缩起来,然后将它们返回给用户。执行此操作的页面非常简单 - 这是 Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    string[] fileNames = Request.QueryString["requests"].Split(',');
    Response.Clear();
    Response.ClearHeaders();
    Response.ContentType = "application/zip";
    string archiveName = String.Format("MsdsRequest-{0}.zip", DateTime.Now.ToString("yyyy-mm-dd-HHmmss"));
    Response.AddHeader("Content-Disposition", "attachment; filename=\"" + archiveName + "\"");

    using (ZipFile zip = new ZipFile())
    {
        foreach (string fileName in fileNames)
        {
            zip.AddFile(String.Format(SiteSettings.PdfPath + "{0}.pdf", msdsFileName), "");
        }
        zip.Save(Response.OutputStream);
    }
    Response.Flush();
}

(在你问之前,如果有人在这个 url 中输入其他值会很好......这些不是安全文件。)

这在我的开发箱上运行良好。但是,在我们的 QA 系统上进行测试时,它会下载压缩文件,但它已损坏。不会引发错误,并且事件日志中不会记录任何内容。

我可能会找到一种在 QA 环境中进行交互式调试的方法,但是由于抛出错误(例如找不到 dll 等)实际上并没有失败,并且它成功地生成了一个非空(但已损坏)的 zip 文件,我想我不会通过单步执行来发现太多。

这是否可能是某种问题,Web 服务器通过某种方式“修复”文件来“帮助”我?

我查看了 http 响应标头,它在我的本地盒子上运行,而不是在 qa 盒子上运行,但是虽然它们略有不同,但我没有看到任何确凿的证据。

作为我拒绝的另一个想法,内容长度对我来说是一种可能性,因为如果内容长度值太小,我想这会使其损坏......但我不清楚为什么会发生这种情况,我不知道认为就是这样,因为如果我尝试压缩并下载 1 个文件,我会得到一个小 zip……而下载多个文件会给我一个更大的 zip。因此,再加上没有记录错误的事实,让我认为 zip 实用程序正在正确查找和压缩文件,而问题出在其他地方。

这是标题,要完整。

我的开发机器上的响应头(工作)

HTTP/1.1 200 OK
Date: Wed, 02 Jan 2013 21:59:31 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Content-Disposition: attachment; filename="MsdsRequest-2013-59-02-165931.zip"
Transfer-Encoding: chunked
Cache-Control: private
Content-Type: application/zip

qa 机器上的响应标头(不工作)

HTTP/1.1 200 OK
Date: Wed, 02 Jan 2013 21:54:37 GMT
Server: Microsoft-IIS/6.0
P3P: CP="NON DSP LAW CUR TAI HIS OUR LEG"
SVR: 06
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Content-Disposition: attachment; filename="MsdsRequest-2013-54-02-165437.zip"
Cache-Control: private
Content-Type: application/zip
Set-Cookie: (cookie junk removed);expires=Wed, 02-Jan-2013 21:56:37 GMT;path=/;httponly
Content-Length: 16969

不知道如何解决这个问题,因为没有任何东西声称失败。我觉得这可能是一个 Web 服务器配置问题(因为我没有更好的想法),但不知道去哪里找。有没有我可以采取的机智?

4

1 回答 1

1

因为它是你错过了End()在 as 之后给页面一个Flush()

 ...
        zip.Save(Response.OutputStream);
    }
    Response.Flush();
    Response.End();
}

但这不是正确的方法,使用页面发送 zip 文件,可能 IIS 也 gZip 页面,这也可能导致问题。正确的方法是使用处理程序,并通过以太网配置 IIS 来避免对该处理程序进行额外的 gZip 压缩,如果您进行 gZip 压缩,请避免为该处理程序进行额外的 gZip 压缩。

例如,为您的案例命名的处理程序download.ashx将如下:

public void ProcessRequest(HttpContext context)
    {
      string[] fileNames = Request.QueryString["requests"].Split(',');          
      context.Response.ContentType = "application/zip";          
      string archiveName = String.Format("MsdsRequest-{0}.zip", DateTime.Now.ToString("yyyy-mm-dd-HHmmss"));          
      context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + archiveName + "\"");

      // render direct
      context.Response.BufferOutput = false;

      using (ZipFile zip = new ZipFile())
      {
        foreach (string fileName in fileNames)
        {
            zip.AddFile(String.Format(SiteSettings.PdfPath + "{0}.pdf", msdsFileName), "");
        }
        zip.Save(context.Response.OutputStream);
      }
    }  
于 2013-01-02T23:43:54.417 回答