Mail folder is always corrupted after upload
For some reason, when I download the zip folder from my server folder, it is always corrupted. Here is the code:
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();
}
}
And this is how the GridView is populated:
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();
}
source to share
I just tried the same code with a .docx file and the same result (file corrupted): Here is the code:
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();
}
source to share
As @lassevk suggested you download the corrupted zip file and compare it with the original file on the server. Are the lengths the same? Use a hex editor to check the contents of the file. In this linked thread, you are saying that if you point the browser directly to the zip file, it will get corrupted as well, which means the problem is probably not headers related, but something wrong with IIS. Are you using third party ISAPI extensions that can modify the file?
source to share
Assuming you need to do this: (for example you cannot provide a direct link)
<a href='<% Eval("Url")) %>'>download</a>
First, I'll make the point that using a RowCommand handler to return a file is not the way to go. Create a link to another page. Separately download files from the rest of the page containing the grid.
Now...
You have the basics right, but as a comment in this CodeProject tutorial , you will run into problems soon.
If the above example code falls down:
- does not respond to user
- the code will continue and you won't have an idea if the user uploaded the file (this may not matter to you)
- won't work with all browsers
- cannot resume download
- does not show progress
- Large files will use more server memory and take longer to stream.
- and a lot of downloads will mean that the server will attack the resource
then as you may want.
- works the same as a click (e.g. with get, not post)
- works in all browsers on all platforms as the user expects (e.g. filename hint works on things like IE for Mac or Netscape 4.1).
- show loading progress
- renewable downloads
- keeping track of all downloads and knowing when downloading is complete
- looks like a file even if it's not
- expiration by url.
- allows you to maintain a high level of simultaneous downloads of files of any size.
Although VB.net1.1 has an article on Tracking and Resuming Large File Uploads in ASP.NET [devx] it explains much better how to do it correctly.
Lightweight code is easy, but doesn't always work, and efficiently streaming files to users. In 100% of cases, it takes a little more work than setting the content header and dragging some bits over the wire.
source to share
First, make sure the contents of the file actually look like a zip file. You can do this by simply dropping the file into notepad and looking at the contents. If the file starts with PK and some funny characters, it might be a zip file. If it contains HTML, that could be a clue as to why this is not happening correctly.
Looking at your code, it seemed to me that you are passing the url to the Response.WriteFile file. Does Response.WriteFile handle url or use local filenames? Maybe everything up to Response.WriteFile is working and hence the correct headers are being sent and so on, but then the code crashes with an exception, which could cause your "zip file" to contain an HTML error message.
Edit . So, the first stage of solving the problem is completed. The file looks like a zip file in notepad, not an HTML error message.
Next step, since the file is on the server, try writing the url directly to the file instead of going through your application. It works?
If not, try a different email program (which one are you using by the way?).
As an example why you should try the file directly and different unzipped programs. FinalBuilder creates zip files that PowerArchiver complains about, but 7zip doesn't, so there might be something wrong with the file, your program, or even both.
But make sure the files are correct, they can be opened and if you don't download them at all, and check what happens if you download them directly outside of your application.
Edit . Ok, you confirmed that the file won't open even if you download it directly from your server.
How about opening the file in just explorer, bypassing the entire web server? For example, since it looks like you have the file locally, try just navigating to the right folder and opening the file directly. It works?
source to share
Here's the updated code:
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();
source to share
Here are the violinist's stats:
HTTP / 1.1 200 OK Server: ASP.NET Development Server / 8.0.0.0 Date: Wed Dec 17 2008 22:22:05 GMT X-AspNet version: 2.0.50727 Content-Disposition: attachment; filename = MyZipFolder.zip Content-Length: 148 Cache-Control: Private Content-Type: application / x-zip-compression Connection: Close
source to share