GridView download files in Subfolders - c#

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>

Related

I'm trying to download PDF file using C# and asp.net

using the following code I'm trying to download pdf file from server path but after clicking on download button file not download but the code gets file name and file path.
I think I'm missing something in code so, please help me out
Thank you in advance..
code is :
protected void btn_Download_Template_Click(object sender, EventArgs e)
{
string mainPath = "";
string fileName = "Self_Declaration.pdf";
mainPath = Server.MapPath("~/Template/Self_Declaration.pdf");
FileInfo file = new FileInfo(mainPath);
if (file.Exists)
{
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename= ~/Template/Self_Declaration.pdf");
Response.AddHeader("Content-Type", "application/pdf");
Response.ContentType = "application/pdf";
Response.WriteFile(file.FullName);
Response.End();
}
else
{
Response.Write("This file does not exist.");
}
}```
Well I don't have enough reputation points to put this in the comment section, but I think your question has already been answered here

Response.TransmitFile() fails to transmit an empty file

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()) \"";

to download a page as pdf file and save in a local folder in C#

protected void btn_download_Click(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=foo.pdf");
string filePath = Server.MapPath(Request.ApplicationPath) + " \\Member\\Attachments" ;
Response.TransmitFile(filePath);
Response.End();
}
I used the above link code to download a webpage to a pdf file and save in a local file. But i am getting the error as access to the path is denied. Please help me out.
Missing local file name in filePath variable. Append file name to it. And make sure that you attachment directory have permission to access files for IIS users.
string filePath = Server.MapPath(Request.ApplicationPath) + " \\Member\\Attachments\\foo.pdf" ; \\Append your file name here.

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.

File is broken when downloading from LinkButton

On my ASP code, I have a LinkButton for my file upload:
<asp:Linkbutton ID="lnkContract" Text="" runat="server" Visible="false" onclick="lnkContract_Click"></asp:Linkbutton>
I manage to write a code in C# that triggers a file download in lnkContract_Click here:
protected void lnkContract_Click(object sender, EventArgs e)
{
string[] strFileType = lnkContract.Text.Split('.');
string strPath = Server.MapPath("~") + FilePath.CUST_DEALS + lnkContract.Text;
Open(lnkContract.Text, strFileType[1], strPath);
}
private void Open(string strFile, string strType, string strPath)
{
FileInfo fiPath = new FileInfo(#strPath);
//opens download dialog box
try
{
Response.Clear();
Response.ContentType = "application/" + strType.ToLower();
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + strFile + "\"");
Response.AddHeader("Content-Length", fiPath.Length.ToString());
Response.TransmitFile(fiPath.FullName);
HttpContext.Current.ApplicationInstance.CompleteRequest();
Response.Clear();
}//try
catch
{
ucMessage.ShowMessage(UserControl_Message.MessageType.WARN, CustomerDefine.NOFILE);
}//catch if file is not found
}
when I click the LinkButton the file automatically downloads but when I open the file, it is broken (or if the file is .jpeg the file shows an "x"). Where did I go wrong?
Update
LinkButton is under UpdatePanel.
Instead of the second Response.Clear(); replace it with Response.End(); to flush the buffer and send all the data to the client.
You will have a problem with your code though, which is, that Response.End() actually causes a Thread abort exception, therefore, you should be more specific in the exception you catch.
UPDATE:
In your comments you mentioned that this is running within an UpdatePanel. In that scenario, this will not work. You will have to force that link button to execute a regular postback instead of an ajax one.
Here's how: https://stackoverflow.com/a/5461736/1373170
Try using this function that I'm shamelessly lifting from http://forums.asp.net/post/3561663.aspx to get the content type:
(Use it with your fiPath.Extension)
public static string GetFileContentType(string fileextension)
{
//set the default content-type
const string DEFAULT_CONTENT_TYPE = "application/unknown";
RegistryKey regkey, fileextkey;
string filecontenttype;
//the file extension to lookup
//fileextension = ".zip";
try
{
//look in HKCR
regkey = Registry.ClassesRoot;
//look for extension
fileextkey = regkey.OpenSubKey(fileextension);
//retrieve Content Type value
filecontenttype = fileextkey.GetValue("Content Type", DEFAULT_CONTENT_TYPE).ToString();
//cleanup
fileextkey = null;
regkey = null;
}
catch
{
filecontenttype = DEFAULT_CONTENT_TYPE;
}
//print the content type
return filecontenttype;
}

Categories

Resources