ASP.NET File Download from Server

ASP.NET file download from server

You can use an HTTP Handler (.ashx) to download a file, like this:

DownloadFile.ashx:

public class DownloadFile : IHttpHandler 
{
public void ProcessRequest(HttpContext context)
{
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition",
"attachment; filename=" + fileName + ";");
response.TransmitFile(Server.MapPath("FileDownload.csv"));
response.Flush();
response.End();
}

public bool IsReusable
{
get
{
return false;
}
}
}

Then you can call the HTTP Handler from the button click event handler, like this:

Markup:

<asp:Button ID="btnDownload" runat="server" Text="Download File" 
OnClick="btnDownload_Click"/>

Code-Behind:

protected void btnDownload_Click(object sender, EventArgs e)
{
Response.Redirect("PathToHttpHandler/DownloadFile.ashx");
}

Passing a parameter to the HTTP Handler:

You can simply append a query string variable to the Response.Redirect(), like this:

Response.Redirect("PathToHttpHandler/DownloadFile.ashx?yourVariable=yourValue");

Then in the actual handler code you can use the Request object in the HttpContext to grab the query string variable value, like this:

System.Web.HttpRequest request = System.Web.HttpContext.Current.Request;
string yourVariableValue = request.QueryString["yourVariable"];

// Use the yourVariableValue here

Note - it is common to pass a filename as a query string parameter to suggest to the user what the file actually is, in which case they can override that name value with Save As...

Download any kind of file in asp.net c#

Thanks for answering my questions. My LinkButton to downloading the file from database on particular user Id worked Successfully.

Actually My Download Link was in update panel so It needs the "Trigger" for this.. And My Link was in GridView So I had Passed the Link Button Id in Trigger.

Whenever we use GridView in Update Panel and There is a LinkButton to Download the File from database on particular user Id. We Should Pass **GridView Id not the LinkButton Id in Template Field.**

 <asp:UpdatePanel ID="upd" runat="server">
<ContentTemplate>
<asp:GridView ID="grd_UserList" runat="server" CssClass="table"
DataKeyNames="Uid" AutoGenerateColumns="false" AllowPaging="false">
<asp:TemplateField HeaderText="Task Name">
<ItemTemplate>
<asp:LinkButton Id="LinkDownload" runat="Server" CommandArgument='<%# Eval("Attachment") %>' >
</ItemTemplate>
</asp:TemplateField>

</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="grd_UserList" />
</Triggers>
</asp:UpdatePanel>

How to let a ASP.NET page know when a file is ready for download from the server

As VDWWD explained ("the UI is never updated because the server can only send one type of response at a time (a file or a html page)") your real problem is that you have no idea when the file download gets completed (or to be exact, when the server-side code, which prepares the file, has finished executing).

There are more than a handful of questions about this here on SO and amazingly almost always the answer is you cannot know!

Well, not quite!

You can always let the client know by sending back a uniquely named cookie containing a time stamp. On the client, the javascript code tries to detect the cookie presence and when it does it hides any loading image (or text or whatever) you've shown.

So, without further ado here's the code (I only used the loading css class to make the sample simpler and smaller):

<form id="form1" runat="server">        
<div class="loading">
Loading. Please wait.<br />
<br />
</div>
<asp:HiddenField ID="windowid" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Download"
OnClick="Button1_Click"
OnClientClick="ShowProgress();" />
</form>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>

<script type="text/javascript">
function ShowProgress() {
$(".loading").show();
checkCookie();
}

function checkCookie() {
var cookieVal = $.cookie($('#<%= windowid.ClientID %>').val());
if (cookieVal == null || cookieVal === 'undefined') {
setTimeout("checkCookie();", 1000);
}
else {
$(".loading").hide();
}
}
</script>

Code-behind VB.NET:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
' the hidden value will be used to uniquely name the cookie and
' will be used both on the server and the client side to
' work with the cookie.
windowid.Value = Guid.NewGuid().ToString()
End If
End Sub

Protected Sub Button1_Click(sender As Object, e As EventArgs)
' for demo purposes only
System.Threading.Thread.Sleep(4000)

GetCsv()
End Sub

Protected Sub GetCsv()
' ...

Dim bytes As Byte() = Encoding.ASCII.GetBytes(sb.ToString())

Response.Clear()
Response.Cookies.Add(New HttpCookie(windowid.Value, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ff")))
Response.AddHeader("Content-Disposition", "attachment; filename=contacts.csv")
Response.AddHeader("Content-Length", bytes.Length.ToString())
Response.ContentType = "text/csv"
Response.Write(sb.ToString())
Response.Flush()
Response.End()
End Sub

Code-behind C#:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// the hidden value will be used to uniquely name the cookie and
// will be used both on the server and the client side to
// work with the cookie.
windowid.Value = Guid.NewGuid().ToString();
}
}

public void GetCsv()
{
// ...
var bytes = Encoding.ASCII.GetBytes(sb.ToString());

Response.Clear();
Response.Cookies.Add(new HttpCookie(windowid.Value, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ff")));
Response.AddHeader("Content-Disposition", "attachment; filename=contacts.csv");
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.ContentType = "text/csv";
Response.Write(sb.ToString());
Response.Flush();
Response.End();
}

protected void Button1_Click(object sender, EventArgs e)
{
// for demo purposes only
System.Threading.Thread.Sleep(2000);

GetCsv();
}

I hope this helps. If it does I suggest we edit the title (and maybe some of the content) of the question so as to help others finally find a working solution to a problem that hasn't been really answered all this time.

Download a file from a remote server using ASP MVC

File(string, string) expects a file name and a mime type, but you are passing the file content as string.

Serve the file directly from your network drive, in this way:

public ActionResult DownloadFile(string id)
{
UploadedDocument document = new UploadedDocument(Int32.Parse(id));
string filetype = Helpers.GetMimeType(document.FilePath);
return File(document.FilePath, filetype);
}

To force download the file (and bypass the default browser settings file handling, e.g. PDF shown in browser), add a filename as third argument of the File method:

return File(document.FilePath, filetype, "myFileName.pdf");

ASP.NET File Download To Client With Cleanup On Server

I personally don't like anything that requires the code to continue to execute after the response has been sent. I would handle this 1 of 3 ways.

  1. Find a way to make the changes entirely in memory without writing to a file. I am not an Open XML expert, so I am not sure if this is possible with that SDK.

  2. Read the file into memory. Delete the file. Return the contents.

  3. Implement a temp folder with a cleanup job (Azure Web Jobs if Azure cloud hosted) that only deletes things that are older than N seconds old.

How to implement a file download in asp.net

Does this help:

http://www.west-wind.com/weblog/posts/76293.aspx

Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition","attachment; filename=logfile.txt");
Response.TransmitFile( Server.MapPath("~/logfile.txt") );
Response.End();

Response.TransmitFile is the accepted way of sending large files, instead of Response.WriteFile.



Related Topics



Leave a reply



Submit