Introduction
This is to show how one can quickly bind an image from a database, which arrives as type byte[]
, and into asp:Image
object on your Web Form.
Background
Having to bind an image from a database to a Web Form is a very frequent task. In the most common scenario you have the following:
- You have a column with an image, which arrives as type
byte[]
; - You have
asp:Image
object on your form that needs to show the image; - You use property
DataSource
and method DataBind()
to bind your records to the containing object, be that GridView
or ListView
or whatever else;
Most of articles that you can find on the Internet will tell you to use something like this:
<asp:Image ImageUrl='<%# "ShowImage.ashx?id=" + Eval("IMG_ID") %>' />
And then you would have to create that ShowImage.ashx file where you need to implement IHttpHandler
that would use the passed ID of the image, read the image and generate a valid response in the end, one that can be automatically recognized as an image.
Problems that I had with this approach:
- If I query my data through a stored procedure, I get the complete image on the first request, and I do not want to query for the same image the second time. Ok, there are some cumbersome suggestions out there for implementing the buffering, but it is a complication.
- To implement a whole extra
IHttpHandler
just to show my JPEG-s sounds like yet another complication, and takes a bit of time.
After much search on the Internet I finally came to the simplest, quickest and most elegant way of achieving exactly what I wanted, and it is explained in the chapter below.
Using the code
Let's assume we have column [IMG_DATA]
that represents our images, and which arrives as type byte[]
.
Set your image object to the following presentation:
<asp:Image ImageUrl='<%# GetImage(Eval("IMG_DATA")) %>' />
Above we tell the ASPX engine that we want to take value of column [IMG_DATA]
, and pass it into method GetImage
of the page, which should return a valid image. So, let's implement the method inside our page class:
public string GetImage(object img)
{
return "data:image/jpg;base64," + Convert.ToBase64String((byte[])img);
}
And this is it, we are done! We are simply returning the image as a well-formatted Base64 string, setting the right header of "data:image/jpg;base64,"
.
And if you want to display other images, like GIF or PNG, then just change the header to "data:image/gif;base64,"
or "data:image/png;base64,"
accordingly.
And if you are an ASPX-only hard-coder, you can use it as shown below:
<asp:Image ImageUrl='<%# "data:image/jpg;base64," + Convert.ToBase64String((byte[])Eval("IMG_DATA")) %>' />
NOTES
- In the examples above, for simplicity I skipped other attributes, like
ID
and runat
, that you will normally use. - The proposed solution comes at a cost: it increases size of the output HTML with embedded images, and thus must be weighted for each project separately, considering size of images and performance requirements. It makes more sense to use for either a single image or a set of small images.
Points of Interest
In my current task I have to use stored procedures from an Oracle database. Some of the procedures return records with images in them, as type Blob
, which arrives into .NET layer as type byte[]
.
Since I already had the image data, while using the standard DataSource
and DataBind()
methods, it beat me why I couldn't find such a basic information about showing images on a form without using the overhead of a custom IHttpHandler
.
It took me a number of hours to find the right answer, and once I did find it, the simplicity of it compelled me to publish this tip for others, not to waste time on such a trivial task.
History
- August 23, 2012 - Initial Version.