DotNetZip 使用 ASP.NET 创建的 Zip 文件有时会导致网络错误
Zip files created by DotNetZip using ASP.NET sometimes causing network error
我正在调试涉及 DotNetZip 和 ASP.NET 的相当奇怪的情况。长话短说,Firefox 可以可靠地下载由代码创建的生成的 zip 文件,但大多数其他浏览器间歇性地返回网络错误。我已经检查了代码,它看起来和任何涉及 DotNetZip 的东西一样一般。
有什么线索吗?
谢谢!
编辑:这是完整的方法。正如我所提到的,它几乎是通用的:
protected void btnDownloadFolders_Click(object sender, EventArgs e)
{
//Current File path
var diRoot = new DirectoryInfo(_currentDirectoryPath);
var allFiles = Directory.GetFiles(diRoot.FullName, "*.*", SearchOption.AllDirectories);
Response.Clear();
Response.BufferOutput = false;
var archiveName = String.Format("{0}-{1}.zip", diRoot.Name, DateTime.Now.ToString("yyyy-MM-dd HHmmss"));
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "inline; filename=\"" + archiveName + "\"");
using (var zip = new ZipFile())
{
foreach (var strFile in allFiles)
{
var strFileName = Path.GetFileName(strFile);
zip.AddFile(strFile,
strFile.Replace("\" + strFileName, string.Empty).Replace(diRoot.FullName, string.Empty));
}
zip.Save(Response.OutputStream);
}
Response.Close();
}
可能是因为您没有发送 content-length
。我已经看到将文件发送到未指定的浏览器时发生错误。所以在 MemoryStream
中创建 zip 文件。将流保存到字节数组,以便您也可以将长度作为响应发送。虽然我不能肯定地说它会解决您的具体问题。
byte[] bin;
using (MemoryStream ms = new MemoryStream())
{
using (var zip = new ZipFile())
{
foreach (var strFile in allFiles)
{
var strFileName = Path.GetFileName(strFile);
zip.AddFile(strFile, strFile.Replace("\" + strFileName, string.Empty).Replace(diRoot.FullName, string.Empty));
}
//save the zip into the memorystream
zip.Save(ms);
}
//save the stream into the byte array
bin = ms.ToArray();
}
//clear the buffer stream
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
//set the correct contenttype
Response.ContentType = "application/zip";
//set the filename for the zip file package
Response.AddHeader("content-disposition", "attachment; filename=\"" + archiveName + "\"");
//set the correct length of the data being send
Response.AddHeader("content-length", bin.Length.ToString());
//send the byte array to the browser
Response.OutputStream.Write(bin, 0, bin.Length);
//cleanup
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
我正在调试涉及 DotNetZip 和 ASP.NET 的相当奇怪的情况。长话短说,Firefox 可以可靠地下载由代码创建的生成的 zip 文件,但大多数其他浏览器间歇性地返回网络错误。我已经检查了代码,它看起来和任何涉及 DotNetZip 的东西一样一般。
有什么线索吗?
谢谢!
编辑:这是完整的方法。正如我所提到的,它几乎是通用的:
protected void btnDownloadFolders_Click(object sender, EventArgs e)
{
//Current File path
var diRoot = new DirectoryInfo(_currentDirectoryPath);
var allFiles = Directory.GetFiles(diRoot.FullName, "*.*", SearchOption.AllDirectories);
Response.Clear();
Response.BufferOutput = false;
var archiveName = String.Format("{0}-{1}.zip", diRoot.Name, DateTime.Now.ToString("yyyy-MM-dd HHmmss"));
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "inline; filename=\"" + archiveName + "\"");
using (var zip = new ZipFile())
{
foreach (var strFile in allFiles)
{
var strFileName = Path.GetFileName(strFile);
zip.AddFile(strFile,
strFile.Replace("\" + strFileName, string.Empty).Replace(diRoot.FullName, string.Empty));
}
zip.Save(Response.OutputStream);
}
Response.Close();
}
可能是因为您没有发送 content-length
。我已经看到将文件发送到未指定的浏览器时发生错误。所以在 MemoryStream
中创建 zip 文件。将流保存到字节数组,以便您也可以将长度作为响应发送。虽然我不能肯定地说它会解决您的具体问题。
byte[] bin;
using (MemoryStream ms = new MemoryStream())
{
using (var zip = new ZipFile())
{
foreach (var strFile in allFiles)
{
var strFileName = Path.GetFileName(strFile);
zip.AddFile(strFile, strFile.Replace("\" + strFileName, string.Empty).Replace(diRoot.FullName, string.Empty));
}
//save the zip into the memorystream
zip.Save(ms);
}
//save the stream into the byte array
bin = ms.ToArray();
}
//clear the buffer stream
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
//set the correct contenttype
Response.ContentType = "application/zip";
//set the filename for the zip file package
Response.AddHeader("content-disposition", "attachment; filename=\"" + archiveName + "\"");
//set the correct length of the data being send
Response.AddHeader("content-length", bin.Length.ToString());
//send the byte array to the browser
Response.OutputStream.Write(bin, 0, bin.Length);
//cleanup
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();