On a recent project we had to write some code to export data files from our system and make them available for download directly from our website. As part of the logging activity we needed to know when these files were being accessed and have this information displayed on our administration pages.
We came up with a couple of ways to do this...
Create a Download.aspx page which creates the log in the Page_Load() method and then redirects to the relevant file.
Create a HttpHandler to do the same functionality.
As we hadn't created a HttpHandler before we thought we'd try it out.
First of all I did the usual developer thing and searched for some ideas via Goggle. The links I found most useful were ...
It is surprisingly simple to create and configure a HttpHandler using Visual Studio 2008 with only a couple of gotchas which i ran into on my way.
1. add a Generic Handler to your project. Ideally you could make another assembly for your handlers and there for make them reusable, but just for a proof of concept we just added it to our web application.
2. The HttpHandler implements the IHttpHandler interface which gives you a ProcessRequest() method and a IsResusable property. You get control of a HttpContext instance and can set the response to whatever you want. In our case we did something a little like this ...
3. Set the IsReusable to be true. Why? - good question - if your HttpHandler doesn't hold onto any request specific state then it's better to set to true so it can be pooled and reused between calls.
4. Set up your web.config to use the handler by adding an entry into the
5. Set up IIS to map the file extension your are handling to the aspnet_iis.dll. This will then pipe all requests for those types of files to your asp.net worker process and it'll use the web.config to work out which handler to use.
NOTE: If you want you handler to be applied to any request regardless of whether the file exists or not then uncheck the 'Verify that file exists' checkbox. Therefore you can handle a request for a file and map it to something complete different. Eg. request for currentdata.xml and return data_20080602.xml (an archived file).
Like I mentioned, there are a few ways of accomplishing this and creating a web service is also an option but given the size of the data we were generating (~50Mb unzipped), and the fact that the client doesn't want zipped data and didn't want to consume a web service with any sort of programmability, makes this solution seem viable.
To extend our solution an make it not so specific to a particular file type we could have mapped our handler to a particular file like "Download.aspx" and take request parameters which the file name or code. Something like ...
or as suggested by a coworker map the handle to a folder and end up with something like "download?file=currentData" which would be cool, but then our urls would be straying away from the microsoft world ;-)
Will update you with further details as we progress/refactor.
The main thing is that we learnt a bit more about HttpHandlers and added another weapon to the arsenal. We also found some other cool ideas for HttpHandlers through these links ...