Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A generic Image-From-DB class for ASP.NET

0.00/5 (No votes)
14 Aug 2011 1  
Getting an image from a database and displaying it in an ASP.NET page is something we have to do quite often. Here is a generic class which does the job for you.
When your user logs in, say, you may wish to pull his avatar from the database and display it on the page - maybe he can't remember who he is, and needs a reminder, or you want to post the users avatar with his messages in a forum.

This isn't a difficult task, but it does need a little fiddling. So, here is the generic class I use for it...

First, you need to embed an image into your webpage:
<img alt="" src="ImageFromDb.ashx" />


You then need to code to access and display the image.
In VS, right click your project, and select "Add new Item"
When the dialog appears, select "Generic Handler" from the list, and call it "ImageFromDb"
Press [ENTER].
The code below will display an image dynamically - replace the content of the file VS created:
<%@ WebHandler Language="C#" Class="ImageFromDb" %>

using System;
using System.Web;
using System.Data.SqlClient;
/// <summary>
/// Read an image from the database and return it as a displayable image.
/// </summary>
public class ImageFromDb : IHttpHandler
    {
    /// <summary>
    /// Kept at class level to prevent needing to pass it through to private methods
    /// </summary>
    private HttpContext context = null;
    /// <summary>
    /// Interface property: Can another instance reuse this one?
    /// </summary>
    public bool IsReusable
        {
        get { return false; }
        }

    /// <summary>
    /// Reads an image from a database as returns it as a image.
    /// (For '[' read less-than, for ']' read greater-than)
    ///     [img alt="" src="ImageFromDb.ashx?db=myDB&table=myTable&field=myField&idName=idField&id=myID" /]
    /// </summary>
    /// <remarks>
    /// Parameters:
    ///    db    : name of database in connection strings - defaults to ImageDatabase
    ///    table : name of table in database containgin image field - defaults to myTable
    ///    field : name of field in table - defaults to image
    ///    idName: name of idField in table
    ///    id    : iD of record in table to extract image from
    /// </remarks>
    /// <param name="context"></param>
    public void ProcessRequest(HttpContext context)
        {
        this.context = context;
        // Read and default parameters
        string db = ReadOrDefault("db", "ImageDatabase");
        string table = ReadOrDefault("table", "myTable");
        string field = ReadOrDefault("field", "image");
        string idName = ReadOrDefault("idName", "id");
        string id = ReadOrDefault("id", "1");
        context.Response.ContentType = "image/JPEG";
        try
            {
            string dbCon = System.Configuration.ConfigurationManager.ConnectionStrings[db].ConnectionString;
            using (SqlConnection con = new SqlConnection(dbCon))
                {
                con.Open();
                string command = string.Format("SELECT {0} FROM {1} WHERE {2}=@ID", field, table, idName);
                SqlCommand com = new SqlCommand(command, con);
                com.Parameters.AddWithValue("@ID", id);
                object o = com.ExecuteScalar();
                if (o != null)
                    {
                    // Image found.
                    context.Response.BinaryWrite((byte[]) o);
                    }
                else
                    {
                    throw new ApplicationException("Requested ID is not in database");
                    }
                }
            }
        catch (Exception ex)
            {
            string err = string.Format("ImageFromDB?{0}&{1}&{2}&{3}&{4} failure", db, table, field, idName, id);
            SMWebSiteUtils.SMUtils.ErrorLog(err, ex.ToString());
            context.Response.WriteFile(@"~\Resources\Images\Problems\NoImageAvailable.png");
            }
        }
    /// <summary>
    /// Reads a value from the instance parameters, and returns it
    /// or the default if not specified.
    /// </summary>
    /// <param name="par">Parameter name to read</param>
    /// <param name="def">Defualt value if not specified</param>
    /// <returns>Parameter value or defualt if paramater not specified</returns>
    private string ReadOrDefault(string par, string def)
        {
        string val = context.Request.QueryString[par];
        if (string.IsNullOrEmpty(val))
            {
            val = def;
            }
        return val;
        }
    }

As describing the the ProcessRequest header, it uses default values for the database connection string name, the table name, the image field name, the id field name, and the id value, so if the defaults are altered to match your system, you do not need to specify them in the img tag. You can override them there if you need to for other purposes though.

The code in the exception is specific to my system: you will want to alter it to fit
how you normally handle errors and reporting - I log it to a errors database, and return a "no such image" image. You will need to change this code as it will not compile for your system! :laugh:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here