Force File Download with ASP.NET (C#)

Today's Browsers are capable of opening many different types of files. For example, if you click on a link to MP3 file, most Browsers will play it within the Browser. But sometimes you may want to provide a 'Download File' link, which will force the Browser to save the target file on user's computer even if the Browser is capable of opening it. Recently I worked on a Website that offered a download option to music files.

In addition to forcing download of a File, you may also want to perform tasks like verifying if the user has access to the File, or keep a count of number of times a File has been downloaded.

The simple trick to force download of a File is adding a HTTP header called content-disposition=attachment. You can also add a file name to this header to suggest a FileName for the Downloaded File.

Here is an ASP.NET example code:

/***********
Author: Abu Haider (http://www.haiders.net)
Nov 2008
Adds Extension Method "ForceDownload" to HttpResponse class
Requires: ASP.NET 3.5
Drop this in App_Code
/************/


public static class HttpExtensions
{
 
  //Forces Download/Save rather than opening in Browser//
  public static void ForceDownload(this HttpResponse Response, string virtualPath, string fileName)
  { 

    Response.Clear();
    Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
    Response.WriteFile(virtualPath);
    Response.ContentType = "";
    Response.End(); 

  } 

} 

The example above is an Extension method for HttpResponse, and will work for ASP.NET 3.5 onwards. If you add this class to App_Code, a new method named 'ForceDownload()' will be available on the Response object. Here is an example you can use anywhere in an ASP.NET Page (Page_Load Event, for example):

Response.ForceDownload("~/Downloads/MyMusic.mp3","MyMusic.mp3");

Calling this method will end the response after sending the File to client.

For ASP.NET 2.0, you can use the body of the Extension method and add it to Page_Load Event directly.

About ContentType

The above Extension Method simply clears the CotnentType header. This is to keep the method generic. If you would like to specify ContentType for the target File, you can add another Parameter to the method and assign it to the ContenType header instead of clearing it. ContentType header is used by the Browser to understand what type of data is being received so they can display it properly or use an associated program to open it. Clearing the ContentType does work in this case since we do not want the Browser to try and open the File with an associated program, but simply save it to disk.

My observation is that if there is no ContentType present, IE uses the file extension to uderstand the content.

 

Posted on November 25, 2008 05:45 by Haider

Comments

November 26. 2008 08:03

Sher

Exactly what I was looking for.

Thanks!

Sher

January 15. 2009 13:23

Dwight Taylor

"If you add this class to App_Code, a new method named 'ForceDownload()' will be available on the Response object"

wheres the rest of the code for the default etc

Dwight Taylor

January 15. 2009 13:40

Dwight Taylor

i added it to the app_code folder as class1.cs and i put the reponse.forcedownload in the default code but its not responding

Error  1  'System.Web.HttpResponse' does not contain a definition for 'ForceDownload' and no extension method 'ForceDownload' accepting a first argument of type 'System.Web.HttpResponse' could be found (are you missing a using directive or an assembly reference?)  C:\Users\Dwight\Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\Default.aspx.cs  14  22  WebApplication1

Dwight Taylor

March 18. 2009 08:17

Lisa Hejny

I had the same problem as Dwight Taylor.  I solved it by calling the following:

HttpExtensions.ForceDownload(System.Web.HttpContext.Current.Response, virtualPath, fileName);

Lisa Hejny

March 31. 2009 06:35

Allison Nighswander

Thank you, exactly what I was looking for.

Allison Nighswander

September 18. 2009 04:01

Tushar Kumar

If you are using AJAX Update panel and trying "FORCE DOWNLOAD" then will cause an error
"Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 500"

To get rid of this make a dummy page, eg. downloadpage.aspx, and on PageLoad write the above code.

Easy solution.

Tushar Kumar

December 25. 2009 06:02

Haider

It has been suggested that Response.TransferFile() is more efficient than Response.WriteFile() as no memory buffering is done with Response.TransferFile().

Something worth a consideration.

Haider

August 12. 2010 13:34

Thiruna

Thanks a Million. I was looking for this for a long time.

Thiruna

August 31. 2010 05:55

Gilles

Hi,

The right method is Response.TransmitFile() not Response.TransfertFile()!

Gilles

Gilles

October 18. 2010 08:17

Art

Could anybody please translate this into VB.NET 3.5 for me? Thanks.

Art

January 5. 2011 04:01

Mohsen Mirshahreza

If you use an update panel then you have problem.
You can add a triger to the update panel and set the ControlID to download button.

Mohsen Mirshahreza

March 8. 2011 18:39

aneesh

thanxs a lot....i got wat i looking for

aneesh

April 17. 2011 20:37

numan

VB.Net code

Public Shared Sub ForceDownload(Response As HttpResponse, virtualPath As String, fileName As String)




  Response.Clear()

  Response.AddHeader("content-disposition", "attachment; filename=" + fileName)

  Response.WriteFile(virtualPath)

  Response.ContentType = ""

  Response.[End]()



End Sub

numan

April 28. 2011 03:35

mred

here you can find a working vb.net version:
it-things.com/.../

mred

May 17. 2011 21:14

vishnu

hi thanks a lot... its working great..... Smile

vishnu

August 24. 2011 04:03

Tushar PArmar

Thanx....
i was looking for this from last 2 days....

Tushar PArmar

October 21. 2011 02:12

Jakes

Thank you for the post. It really help a lot

Jakes

October 31. 2011 00:39

Rajesh

Can you plase suggest the header format required for android browsers. Because, above suggested code wont work in android browsers.

Rajesh

November 9. 2011 07:04

Highlander

Hein dude
i Found a little bug in the code
this codes fails in "SSL +  IE 6.0 to IE 8.0" environment
Check how to solve it, funny ! but i found the solution in the same site ! tks again

public static void ForceDownload(this HttpResponse Response, string virtualPath, string fileName)
{
           Response.Clear();

            Response.ClearHeaders(); //solve the  bug  IE 6 - IE 8.0 + SSL
            Response.AddHeader("content-disposition", "attachment; filename=" + fileName);

            Response.WriteFile(virtualPath);

            Response.ContentType = "";
            Response.End();    
}

www.haiders.net/.../...e-Download-with-ASPNET.aspx

Highlander

November 9. 2011 07:07

Highlander

Fixing the last post

the correct URL IS
mark.koli.ch/.../...emoving-the-pragma-header.html

Explain how to solve the  bug  IE 6 - IE 8.0 + SSL

it wasn´t the same web site, sorry !

Highlander

February 24. 2012 13:24

Frank

How do you download multiple mp3 in one click?

Thanks

Frank

April 23. 2012 08:30

Marco

Great solution! Thanks a lot!

Marco