Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
I frequently store documents in the database for my ASP.NET apps, eliminating web farm complications with shared drives, permissions, etc. When uploading a file, my Document class reads the uploaded file, zips the file with SharpZipLib, and inserts/updates in the database. When opening a file, I have always used an ASPX page that uses the Document class to unzip the file, and then changes the Content-Disposition and ContentType headers, and then does a BinaryWrite to the Response object to display the file.
I have been using Handlers a lot lately, and figured that it was time to make this process a little more elegant. If you've never written a handler, it's quite simple. You need to make a web.config change, and add a new class that implementts IHttpHandler. All of the work is done in ProcessRequest. Using the default .ashx extension for the handler eliminates the need to make any changes in IIS. I thought about changing the handler to accept all requests with known file extensions with the document ID as the filename, like 3383.pdf. I just figured that using the default extnesion would be easier. Laziness or efficiency, you decide. Check out the code.
In <system.web> in web.config: <httpHandlers> <add verb="*" path="DocumentHandler.ashx" type="TestingWebApp.DocumentHandler, TestingWebApp" /> </httpHandlers> DocumentHandler.cs: using System;using System.Web;namespace TestingWebApp{ public class DocumentHandler : IHttpHandler { private int DocumentId { get { if(System.Web.HttpContext.Current.Request.QueryString["DocumentId"] != null && System.Web.HttpContext.Current.Request.QueryString["DocumentId"].ToString().Length > 0) return Convert.ToInt32(System.Web.HttpContext.Current.Request.QueryString["DocumentId"]); else throw new ApplicationException("Document Handler requires a DocumentId"); } } #region IHttpHandler Members public void ProcessRequest(System.Web.HttpContext context) { context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.BufferOutput = false; Document document = Document.GetDocumentByDocumentId(this.DocumentId); byte[] buffer = document.UnzippedBinary; context.Response.ContentType = document.ContentType; context.Response.OutputStream.Write(buffer, 0, buffer.Length); } public bool IsReusable { get { return true; } } #endregion }}
DocumentHandler.cs: using System;using System.Web;namespace TestingWebApp{ public class DocumentHandler : IHttpHandler { private int DocumentId { get { if(System.Web.HttpContext.Current.Request.QueryString["DocumentId"] != null && System.Web.HttpContext.Current.Request.QueryString["DocumentId"].ToString().Length > 0) return Convert.ToInt32(System.Web.HttpContext.Current.Request.QueryString["DocumentId"]); else throw new ApplicationException("Document Handler requires a DocumentId"); } } #region IHttpHandler Members public void ProcessRequest(System.Web.HttpContext context) { context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.BufferOutput = false; Document document = Document.GetDocumentByDocumentId(this.DocumentId); byte[] buffer = document.UnzippedBinary; context.Response.ContentType = document.ContentType; context.Response.OutputStream.Write(buffer, 0, buffer.Length); } public bool IsReusable { get { return true; } } #endregion }}
Remember Me
a@href@title, strike