Library code snippets

Using ASHX files to retrieve DB images

ASP.NET has a little-known feature that allows you to easily implement what is known as an HTTP Handler. Basically, when a request for a page comes into ASP.NET, eventually that request is handled by an object that implements the IHttpHandler interface. This interface includes a method called "ProcessRequest" that is responsible for writing all of the page content to the HttpContext.Response.Output stream. ASHX files allow you to easily write the IHttpHandler class without even having to pre-compile it. I used ASHX files in a recent project (coming soon) to retrieve images out of a SQL database. Here's how I did it.

You need to create a file in your project with an ASHX extension. I'm retrieving data from the Employees table of the Northwind sample database, so I called my page NWEmpPhoto.ashx. The contents of the ASHX file are as follows:

<%@ webhandler language="C#" class="NWEmpPhotoHandler" %>
using System; 
using System.Web; 
using System.Data; 
using System.Data.SqlClient; 
public class NWEmpPhotoHandler : IHttpHandler 
{ 
    public bool IsReusable { get { return true; } } 
    
    public void ProcessRequest(HttpContext ctx) 
    { 
        string id = ctx.Request.QueryString["id"]; 

        SqlConnection con = new SqlConnection(<<INSERT CONNECTION STRING HERE>>); 
        SqlCommand cmd = new SqlCommand("SELECT Photo FROM Employees WHERE EmployeeID = @EmpID", con); 
        cmd.CommandType = CommandType.Text; 
        cmd.Parameters.Add("@EmpID", id); 
        
        con.Open(); 
        byte[] pict = (byte[])cmd.ExecuteScalar(); 
        con.Close(); 

        ctx.Response.ContentType = "image/bmp"; 
        ctx.Response.OutputStream.Write(pict, 78, pict.Length - 78); 
    } 
} 

As you can see, it's basically source code with the special <% webhandler %> tag at the top. The class implements two methods - IsReusable and ProcessRequest. IsReusable is for handler pooling, and as far as I can tell can be safely hard coded to return true, at least in this scenario. The ProcessRequest method implements the database access. It does some fairly straight forward ADO.NET to retrieve the image from the DB as a byte array. The primary key to the query is passed in on the query string. I'm using ExecuteScalar since I'm retrieving a single column from a single row. The photo column is returned as a byte array. We set the Response's correct content type (image/bmp in this case) and write the byte array containing the picture to the Response.OutputStream. By the way, the 78 byte offset is Northwind database specific. I'm not sure why the bitmap starts 78 bytes into the blob, but I was clued into the fact by an article by Dino Esposito .

To use the NW Photo Handler, you simply use an HTML image tag. Since the primary key is passed in on the query string, you need to include it as the src attribute of the image tag. Here's an example of the image tag:

<img src="NWEmpPhoto.ashx?id=1" />

Comments

  1. 09 May 2007 at 10:29

    Hi

    I read your post its realy nice. kindly explan how to pass ID with <img> or <asp:image>

     

     

  2. 13 Nov 2006 at 16:33

    Brilliant piece of code - and is far faster than a standard aspx page

    If a suggestion is in order - a trap to see if a value is returned and if not, to show a blank image ( thus not showing the broken image link

    if (pict.Length > 0){
            ctx.Response.ContentType = "image/jpeg";
            ctx.Response.OutputStream.Write(pict,0,pict.Length);
          }
     else {
       Image pict2 = Image.FromFile("C:\\somedirectory\\blankimage.gif");
      ctx.Response.ContentType="image/jpeg";
      pict2.Save(ctx.Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg);






    }

    This however bombs out on pict.Length if no id is supplied - any suggestions ??

  3. 22 Apr 2006 at 19:00

    Thank you, thank you, thank you!  

    For those gurus out there, I hope I am not gushing too much.  I have been working for a week trying to find out how to get a pdf out of sql server in asp.net 2.0.  I made one small code tweak to the above and it worked flawlessly!!!  Thanks Again.... I'll buy the beer next time you are in Massachusetts!!!! 

    Here's my tweak:  I just call the page with http://mysite.com/handler.ashx?id=xxx  and viola!

    <%

    @ webhandler language="C#" class="NWEmpPhotoHandler" %>

    using

    System;

    using

    System.Web;

    using

    System.Data;

    using

    System.Data.SqlClient;

    public

    class NWEmpPhotoHandler : IHttpHandler

    {

    public bool IsReusable { get { return true; } }

    public void ProcessRequest(HttpContext ctx)

    {

    string id = ctx.Request.QueryString["id"];

    SqlConnection con = new SqlConnection("Data Source=server;Initial Catalog=schema;Persist Security Info=True;User ID=userid;Password=password");

    SqlCommand cmd = new SqlCommand("SELECT Image FROM mytable WHERE DocID = @DocID", con);

    cmd.CommandType =

    CommandType.Text;

    cmd.Parameters.Add(

    "@DocID", id);

    con.Open();

    byte[] pict = (byte[])cmd.ExecuteScalar();

    con.Close();

    ctx.Response.ContentType =

    "application/pdf";

    // ctx.Response.OutputStream.Write(pict, 78, pict.Length - 78);

    ctx.Response.BinaryWrite(pict);

    }

    }

     

  4. 01 Jan 1999 at 00:00

    This thread is for discussions of Using ASHX files to retrieve DB images.

Leave a comment

Sign in or Join us (it's free).

Harry Pierson

Want to stay in touch with what's going on? Follow us on twitter!