出于某种原因,当我从服务器的文件夹下载zip文件夹时,它总是被破坏。这是代码:
protected void gvFiles_RowCommand(object sender, System.Web.UI.WebControls.GridViewCommandEventArgs e)
{
string fileUrl = String.Empty;
if(e.CommandName.Equals("DownloadFile"))
{
fileUrl = e.CommandArgument as String;
string fileName = Path.GetFileName(fileUrl);
Response.AppendHeader("content-disposition",
"attachment; filename=" + fileName);
Response.ContentType = "application/zip";
Response.WriteFile(fileUrl);
Response.End();
}
}
以下是GridView的填充方式:
private void BindData()
{
List<SampleFile> files = new List<SampleFile>();
for(int i=1;i<=3;i++)
{
SampleFile sampleFile = new SampleFile();
sampleFile.Name = "File " + i;
sampleFile.Url = Server.MapPath("~/Files/File"+i+".txt");
files.Add(sampleFile);
}
SampleFile file = new SampleFile();
file.Name = "Zip File";
file.Url = Server.MapPath("~/Files/WebSiteNestedMasters.zip");
files.Add(file);
gvFiles.DataSource = files;
gvFiles.DataBind();
}
答案 0 :(得分:1)
我根本不知道asp.net,但这通常是以文本模式而不是二进制模式进行下载的结果。行结束字符从\ r \ n转换为\ n,反之亦然,一切都很疯狂。
答案 1 :(得分:1)
正如@lassevk建议你应该下载损坏的 zip文件并将其与服务器上的原始文件进行比较。两者长度都一样吗?使用十六进制编辑器检查文件的内容。在这个related thread中你要说的是,如果你将浏览器直接指向zip文件,它也会被破坏,这意味着问题可能与标题无关,但IIS有问题。您是否正在使用可以修改文件的某些第三方ISAPI扩展?
答案 2 :(得分:1)
假设您需要这样做:(例如,您无法提供直接链接)
<a href='<% Eval("Url")) %>'>download</a>
我首先要观察一下RowCommand处理程序开始返回文件不是这样做的方法。创建一些到不同页面的下载链接。从包含网格的页面的其余部分单独下载文件。
现在......
你已经掌握了正确的基础知识,但就像this CodeProject tutorial中的评论一样,你很快就会遇到问题。
上述代码示例落在何处 下:
- 无法响应用户
- 代码将继续运行,你将没有 用户实际下载的想法 文件(对你来说可能无关紧要)
- 不适用于所有浏览器
- 无法恢复下载
- 未显示进度
- 较大的文件将使用更多的服务器内存并需要更长的时间来流式传输
- 并且大量下载意味着服务器将采用资源打击
而你可能想要..
- 就像点击下载一样(即使用get,而不是post)
- 以用户期望的方式在所有平台上的所有浏览器中运行 (即文件名提示适用于类似的东西 IE for Mac或Netscape 4.1)。
- 显示下载进度
- 可恢复的下载
- 跟踪所有下载并了解下载完成时间
- 看起来像一个文件,即使它不是
- 在网址上过期。
- 允许任何大小的文件的高并发#下载量
虽然用VB .net1.1编写,但文章Tracking and Resuming Large File Downloads in ASP.NET [devx]更能说明如何正确地解决这个问题。
简单的代码很容易,但并不总是有效,并且有效地将文件流式传输给用户100%的时间比设置内容标题和铲除一些内容需要更多的努力。
答案 3 :(得分:0)
首先,验证文件的内容实际上看起来像zip文件。您只需将文件放入记事本,然后查看内容即可。如果文件以PK和一些有趣的字符开头,则可能是zip文件。如果它包含HTML,那可能就是为什么它出错了。
查看你的代码,让我感到震惊的是你将url传递给了Response.WriteFile文件。 Response.WriteFile是处理url还是使用本地文件名?也许响应Response.WriteFile的一切都可以工作,因此发送了正确的标题等,但是代码崩溃时会出现异常,这可能会使您的“zip文件”包含HTML错误消息。
修改:好的,首先解决问题的步骤已经完成。文件在记事本中看起来像一个zip文件,而不是HTML错误消息。
下一步,由于文件驻留在服务器上,请尝试直接将文件写入文件,而不是通过您的应用程序。这有用吗?
如果没有,请尝试使用其他拉链程序(顺便使用哪一个?)。
作为为什么你应该直接尝试文件和不同的解压缩程序的一个例子。 FinalBuilder会生成PowerArchiver抱怨的zip文件,但是7zip没有,所以文件或程序可能都有问题,甚至两者都可能出错。
但要验证文件是否正确,可以打开,如果你根本不下载它们,并检查如果你直接在你的应用程序之外下载会发生什么。
修改:好的,即使您直接从服务器下载文件,也确认该文件无法打开。
如何在浏览器中打开文件,完全绕过Web服务器?例如,由于看起来您在本地拥有该文件,请尝试导航到正确的文件夹并直接打开该文件。这有用吗?
答案 4 :(得分:0)
以下是更新后的代码:
fileUrl = e.CommandArgument as String;
string fileName = Path.GetFileName(fileUrl);
FileStream fs = new FileStream(fileUrl, FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int) fs.Length);
fs.Close();
Response.Clear();
Response.AppendHeader("content-disposition",
"attachment; filename=" + fileName);
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-length", buffer.Length.ToString());
Response.BinaryWrite(buffer);
Response.Flush();
Response.End();
答案 5 :(得分:0)
这是小提琴手的统计数据:
HTTP / 1.1 200好的 服务器:ASP.NET Development Server / 8.0.0.0 日期:2008年12月17日星期三,格林威治标准时间22:22:05 X-AspNet-版本:2.0.50727 内容 - 处理:附件;文件名= MyZipFolder.zip 内容长度:148 缓存控制:私有 内容类型:application / x-zip-compressed 连接:关闭
答案 6 :(得分:0)
我刚用.docx文件尝试了相同的代码并且结果相同(文件已损坏):这是代码:
if(e.CommandName.Equals("DownloadFile"))
{
fileUrl = e.CommandArgument as String;
string fileName = Path.GetFileName(fileUrl);
FileInfo info = new FileInfo(fileUrl);
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.AppendHeader("Content-Length",info.Length.ToString());
Response.ContentType = GetContentType(fileUrl);
Response.AppendHeader("Content-Disposition:", "attachment; filename=" + fileName);
Response.TransmitFile(fileUrl);
Response.Flush();
Response.End();
}