我们有一个网页,它从网址抓取一系列字符串,找到一些与这些字符串关联的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();
}
(在你问之前,如果有人在这个网址中添加了其他值,那就没关系...这些不是安全文件。)
这在我的开发盒上工作正常。但是,在我们的QA系统上进行测试时,它会下载压缩文件,但它已损坏。不会引发任何错误,并且事件日志中不会记录任何内容。
我可能有可能找到一种在QA环境上进行交互式调试的方法,但是因为没有任何东西实际上是通过抛出错误而失败(例如,如果找不到dll等),并且它已成功生成一个非空(但腐败)的zip文件,我想我不会通过它来发现它。
这可能是某种问题,网络服务器通过某种方式“修复”文件来“帮助”我吗?
我查看了http响应标题,它在我的本地方框上工作而没有在qa盒子上工作,但是虽然它们略有不同但我没有看到任何吸烟枪。
作为我拒绝的另一个想法,内容长度对我来说是可能的,因为如果内容长度值太小我想这会使它腐败......但我不清楚为什么会发生这种情况我不要以为这就是它,因为如果我尝试压缩和下载1个文件我得到一个小拉链...而下载几个文件给我一个更大的拉链。因此,结合没有记录错误的事实,让我认为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服务器配置问题(因为我没有任何更好的想法),但我不知道在哪里看。我能采取一种机智吗?
答案 0 :(得分:1)
因为您错过了在End()
之后立即向Flush()
提供的内容:
...
zip.Save(Response.OutputStream);
}
Response.Flush();
Response.End();
}
但这不是正确的方法,使用页面发送zip文件,可能IIS也gZip页面,这可能会导致问题。 The correct way is to use a handler并且还可以通过以太网配置IIS来避免对该处理程序进行额外的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);
}
}