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;
public class ImageFromDb : IHttpHandler
{
private HttpContext context = null;
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
this.context = context;
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)
{
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");
}
}
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: