Asp.net: File Download Handler
Recently I had the need to make a file download page where statistics could be collected and saved on each individual download. After a little research I found a nice way to get this task done easily.
Because it is only collecting stats about the download and then sending the file to the browser, I decided to use an Asp.net Generic Handler.
Download.ashx.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.IO; namespace WriteFileTest { [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Download : IHttpHandler { private string FilesPath { get { return @"C:\Users\John Boker\Documents\Visual Studio 2008\Projects\WriteFileTest\Files\"; } } public void ProcessRequest(HttpContext context) { string filename = context.Request.QueryString["file"]; if (!string.IsNullOrEmpty(filename) && File.Exists(FilesPath + filename)) { context.Response.ContentType = "application/octet-stream"; context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", filename)); context.Response.WriteFile(FilesPath + filename); } else { context.Response.ContentType = "text/plain"; context.Response.Write("Invalid filename"); } } public bool IsReusable { get { return false; } } } }
One advantage to this method is the files do not have to be in the website directories and public, extra authentication can be done and the download can be disallowed if necessary.
To test this i created a small Default.aspx page containing:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WriteFileTest._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <a href="Download.ashx?file=FileZilla_3.3.0.1_win32-setup.exe&d=<%= DateTime.Now.Ticks %>">FileZilla_3.3.0.1_win32-setup.exe</a> <br /> <a href="Download.ashx?file=gimp-2.6.7-i686-setup.exe&d=<%= DateTime.Now.Ticks %>">gimp-2.6.7-i686-setup.exe</a> <br /> <a href="Download.ashx?file=jdk-6u17-windows-x64.exe&d=<%= DateTime.Now.Ticks %>">jdk-6u17-windows-x64.exe</a> <br /> <a href="Download.ashx?file=WampServer2.0i.exe&d=<%= DateTime.Now.Ticks %>">WampServer2.0i.exe</a> </div> </form> </body> </html>
As you can see i added another argument to the QueryString; this is to keep the browser from caching files with the same link and filename.


This was a very simple method to take care of multiple issues including:
- Download Tracking
- Alternate File Locations
- Browser Caching Issues
- Extra Authentication
| Attachment | Size |
|---|---|
| WriteFileTest.zip | 10.21 KB |
Comments
I doubt that even Jon Skeet
I doubt that even Jon Skeet himself could put together something this clean and elegant.
Jon Skeet would write this
Jon Skeet would write this with two lines of code with each line no longer than 8 characters.
Post new comment