Response.TransmitFile() fails to transmit an empty file - c#

I'm implementing a column in GridView to allow users to download files when they click on the file name(files are stored in Uploads folder of my Project).
Code is working fine when there's some data in the file i.e. user can click on file and it'll get downloaded but when a user clicks on a file which is empty (like an empty .docx file) a blank page is shown instead of downloading the file.
here's the code:
else if (e.CommandName == "Download")
{
Response.Clear();
if (File.Exists(Server.MapPath("~/Uploads/") + e.CommandArgument))
{
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "filename=" + e.CommandArgument.ToString());
Response.TransmitFile(Server.MapPath("~/Uploads/") + e.CommandArgument);
Response.End();
}
else
{
lblMessage.ForeColor = System.Drawing.Color.Red;
lblMessage.Text = "File Not Found";
}
}
I've tested on Chrome, Mozilla and IExplorer.

you need change this line:
Response.AppendHeader("Content-Disposition", "filename=" + e.CommandArgument.ToString());
for this one:
Response.AppendHeader("Content-Disposition", filename=\"" + e.CommandArgument.ToString()) \"";

Related

Trying to dynamically create a zip file causes the zip file to be corrupted

So i wrote this program for my company that dynamically makes a zip folder in their downloads. This code worked perfectly, however, when my server was updated to windows 10, when i attempt to unzip the file, I get this error.
"Cannot complete the compressed folder"
string[] ProductNumberAmount = prodNumber.ToString().Split(' ');
int amountOf = ProductNumberAmount.Count();
Response.ClearHeaders();
Response.ClearContent();
using (ZipFile zip = new ZipFile())
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=" + ProductNumberAmount[0] + "_" + DateTime.Now.ToString("yyyyMMdd") + ".zip");
for (int i = 0; i < amountOf;)
{
string productNumberList = ProductNumberAmount[i];
productNumberList = productNumberList.Replace("\r\n", string.Empty);
string s = "example text";
File.WriteAllText(#"product_detail_" + productNumberList + ".inc", s);
zip.AddFile(#"product_detail_" + productNumberList + ".inc");
i++;
}
zip.Save(Response.OutputStream);
}
Response.Flush();
HttpContext.Current.Response.End();
}
When viewing the zipped folder that was created in notepad, instead of the normal hex text that you would see, there is html text
Again, this exact code worked perfectly before the update so does this have something to do with the IIS server properties being changed. I have been working on this for a couple days and still have not had any luck with anything
Thank you all for your answers! It was an easier fix then anticipated. I set a breakpoint at
"Response.AddHeader("content-disposition", "attachment; filename=" + ProductNumberAmount[0] + "_" + DateTime.Now.ToString("yyyyMMdd") + ".zip");"
and it threw an exception showing that there was folder that needed permission set. Once i have the user "IIS_IUSRS" full permissions in the named folder, the program worked as it originally was intended.
The reason that it probably needed full permissions was because the zipped folder would go directly into the users downloaded folder

Excel file does not open in browser

I am using aspose to find specific text and highlight it and open that excel file in browser.
Problem is it find and highlight and excel file get downloaded, which i dont want i want to show the contents of excel in browser.
For pdf this works perfectly fine, opens up in browser
PDF code -
if (docBytes != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", docBytes.Length.ToString());
Response.BinaryWrite(docBytes);
}
Here is my code - (excel) - Does not open excel in browser
using (MemoryStream docStream = new MemoryStream())
{
workbook.Save(docStream, Aspose.Cells.SaveFormat.Xlsx);
docBytes = docStream.ToArray();
}
if (docBytes != null)
{
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition",
"attachment; filename=" + "yourExcelFileName.xlsx");
Response.AddHeader("content-length", docBytes.Length.ToString());
Response.BinaryWrite(docBytes);
Response.End();
}
Look at these lines.
Response.AppendHeader("content-disposition",
"attachment; filename=" + "yourExcelFileName.xlsx");
The "attachment" part tells the browser that this file should be downloaded and not displayed in the browser.
Remove that and it should work (in browser that can host Excel at least, so Internet Explorer and possibly Edge).
Response.AppendHeader("content-disposition", "filename=yourExcelFileName.xlsx");
You can read about the attachment parameter over on MDN.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
I think you may try the line instead if it makes any difference:
Response.AppendHeader("content-disposition",
"inline; filename=" + "yourExcelFileName.xlsx");

Download PDF file from a Directory Listing

I have used a Gridview Control to display the contents of a directory in asp.net webforms.
The contents are filtered to display only PDF files.
I also have a Button inside a TemplateField. On the click of the button the user should be able to download and save the PDF file.
The columns displayed in the Gridview are File Name, Modified Date and Size.
How can I program the Button click to download and save the PDF file?
I have a function that performs a file download.
public static void DownloadFile(string FilePath, System.Web.HttpResponse response)
{
System.IO.FileInfo file = new System.IO.FileInfo(FilePath);
if ((file.Exists))
{
response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
response.AddHeader("Content-Length", file.Length.ToString());
response.ContentType = "application/octet-stream";
response.WriteFile(file.FullName);
response.End();
response.Close();
file = null;
}
}
The FilePath parameter is the physical path, so if you have the virtual path (e.g. ~/Folder/file.pdf) might need to use the Server.MapPath(...) function to call the function.
In your Button click event, write the following code.
protected void Button1_Click(object sender, EventArgs e)
{
Response.ContentType = "Application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=Your_Pdf_File.pdf");
Response.TransmitFile(Server.MapPath("~/Files/Your_Pdf_File.pdf"));
Response.End();
}

GridView download files in Subfolders

I have a GridView with data in it, including filenames, I can download files only from one folder and cannot download the files in the subfolders. I have been using this
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Download")
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "filename=" + e.CommandArgument);
Response.TransmitFile(Server.MapPath("Upload\\Track\\Files") + e.CommandArgument);
Response.End();
}
}
I have tried adding this, but I get an error stating its illegal.
string path = Server.MapPath("\\Upload\\Track\\Files\\ ,*," + SearchOption.AllDirectories);
Response.TransmitFile(path + e.CommandArgument);
I want to be able to download all files including the ones in the subfolders, using this method.
UPDATED -- I have also tried this way, but no success, I know I can get the right path, but it just doesn't download.
string path = Server.MapPath("\\Upload\\Track\\Files");
string filename = e.CommandArgument.ToString();
DirectoryInfo dir = new DirectoryInfo(path);
string pathString = System.IO.Path.Combine(dir + path);
if (e.CommandName == "Download")
{
System.IO.Directory.GetDirectories(path);
if (File.Exists(pathString)) {
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "filename=" + filename);
Response.TransmitFile(pathString);
Response.End();
So I have found a solution to my question, I have added a field in my database which holds information about the path - I get this path from when I upload the files, which captures the path and adds it to the database. I have also added the below code to the uploads field in my GridView.
This solution is best for me at the moment, but of course can be improved.
<asp:TemplateField HeaderText="Quote" InsertVisible="false">
<ItemTemplate>
<%# Eval("Uploads") %>
</ItemTemplate>
</asp:TemplateField>

Download files based on their type, or how to give two options to Response.AppendHeader

I am allowing users to download either a PDF file or a zip file, and when they try to download the file, I want the appropriate file to be downloaded according to its type. For example: if the uploaded file is PDF, then it should be downloaded as a PDF; if the uploaded file is zip, then it should downloaded as a zip file.
I have written this code and I am able to download the files as PDF using "output.pdf" in the append header, but don't know how to give two options to append header so that it downloads the file according to its type.
protected void gridExpenditures_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Download")
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "FileName=" + e.CommandArgument + "output.pdf");
Response.TransmitFile(Server.MapPath("~/Match/Files/") + e.CommandArgument);
Response.End();
}
}
You can use a utility like this one to detect the content type of the file in question, then render the header like this:
protected void gridExpenditures_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Download")
{
var filePath = Server.MapPath("~/Match/Files/") + e.CommandArgument;
var contentType = MimeTypes.GetContentType(filePath);
if (string.IsNullOrEmpty(contentType))
{
contentType = "application/octet-stream";
}
Response.Clear();
Response.ContentType = contentType;
Response.AppendHeader("content-disposition", "FileName=" + e.CommandArgument);
Response.TransmitFile(filePath);
Response.End();
}
}
You need to set your content type to the appropriate application, instead of octet-stream.
For example I had this to open PowerPoint:
application/vnd.openxmlformats-officedocument.presentationml.presentation
Look up your file type in this link:
http://en.wikipedia.org/wiki/Internet_media_type
I store the uploaded content type in my database for each file.

Categories

Resources