12.3.1 Problem Your application stores images in a database that you want to display on a web form. 12.3.2 Solution Create a web form that reads the image data from the database and streams the image to the Response object. In the .aspx file, enter an @ Page directive ”omitting any head or body tags to link the .aspx page to the code-behind class that retrieves and displays the images. -
Read the image ID that is generated by the running application ”for example, the image ID passed in the URL for accessing the web form. -
Open a connection to the database that contains the images. -
Build a query string, and read the byte array of the desired image from the database. -
Set the content type for the image and write it to the Response object. Example 12-10 through Example 12-12 show the .aspx file and VB and C# code-behind files for an application that implements the image-building portion of the solution. To use this dynamic image generation technique in your application, set the src attribute of the image tags used to display the images to the URL of the ASP.NET page that reads the images from the database, passing the image ID in the URL. In the .aspx file for the page, add an img tag for displaying the image. In the code-behind class for the page that uses the image, use the .NET language of your choice to set the src attribute of the image tag to the URL for the web form just described, passing the ID of the image in the URL. Example 12-13 through Example 12-15 show the .aspx file and VB and C# code-behind files for an application that uses the dynamic image generation. Figure 12-3 shows some typical output from the application. Figure 12-3. Displaying images from a database 12.3.3 Discussion If you have images in a database that you want to display on a web form, chances are you've considered using an image tag to display them. Nevertheless, you may be searching for a practical way to set the image tag's src attribute and move the image data to the browser while maintaining the maximum flexibility in selecting the images you need. The solution we favor that meets these requirements involves creating a web form that reads an image from a database and streams it to the Response object. A convenient way to specify the image to read from the database is to include an image ID in the URL used to call the web form that retrieves and returns the image to the browser. Our example that illustrates this solution consists of two web forms. The first web form renders no HTML but instead processes the request for reading an image from the database. The second web form is used to demonstrate displaying an image from the database. The .aspx file of the first form contains no head or body; it simply contains the @ Page directive to link the page to its code-behind class. The Page_Load method of the code-behind performs the following steps to retrieve the requested image from the database and then send it to the browser: -
Retrieve the ID of the requested image from the URL -
Read the byte array of the image from the database -
Set the ContentType of the type of image stored in the database (GIF in this example) -
Write the byte array of the image to the Response object To use the ASP.NET page to retrieve images from the database, we need to set the src attribute of an image tag to the name of the page just described, passing the ID of the desired image in the URL. A sample URL is shown here: src="CH12ImageFromDatabaseVB.aspx?ImageID=5" In our example, the src attribute of an img tag is set in the view image button click event of the test page code-behind. To make things a little easier and avoid hardcoding page names and querystring information, two constants ( PAGE_NAME and QS_IMAGE_ID ) are defined in the code-behind of the page that reads the images from the database and are used here in building the URL. The performance of this solution can be significantly improved by caching the images retrieved from the database instead of retrieving them for each request. Refer to Recipe 13.2 for an example of how to cache the results as a function of the data passed in the QueryString . An HttpHandler can be used to implement the same functionality described in this recipe. Refer to Recipe 17.1 for an example of retrieving images from a database using an HttpHandler . Images can be stored in a database using the technique described in Recipe 15.4. 12.3.4 See Also Recipe 13.2; Recipe 15.4; Recipe 17.1 Example 12-10. Reading images from a database (.aspx) <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH12ImageFromDatabaseVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH12ImageFromDatabaseVB" %> Example 12-11. Reading images from a database code-behind (.vb) Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH12ImageFromDatabaseVB.aspx.vb ' ' Description: This module provides the code behind for the ' CH12ImageFromDatabaseVB.aspx page. ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Configuration Imports System.Data Imports System.Data.OleDb Imports System.IO Namespace ASPNetCookbook.VBExamples Public Class CH12ImageFromDatabaseVB Inherits System.Web.UI.Page 'constants used to create URLs to this page Public Const PAGE_NAME As String = "CH12ImageFromDatabaseVB.aspx" Public Const QS_IMAGE_ID As String = "ImageID" '*************************************************************************** ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '--------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim dbConn As OleDbConnection Dim dCmd As OleDbCommand Dim imageData( ) As Byte Dim strConnection As String Dim strSQL As String Dim imageID As String If (Not Page.IsPostBack) Then Try 'get the ID of the image to retrieve from the database imageID = Request.QueryString(QS_IMAGE_ID) 'get the connection string from web.config and open a connection 'to the database strConnection = _ ConfigurationSettings.AppSettings("dbConnectionString") dbConn = New OleDb.OleDbConnection(strConnection) dbConn.Open( ) 'build the query string and get the data from the database strSQL = "SELECT ImageData " & _ "FROM BookImage " & _ "WHERE BookImageID=?" dCmd = New OleDbCommand(strSQL, dbConn) dCmd.Parameters.Add(New OleDbParameter("BookImageID", imageID)) imageData = CType(dCmd.ExecuteScalar( ), Byte( )) 'set the content type for the image and write it to the response Response.ContentType = "image/gif" Response.BinaryWrite(imageData) Finally 'clean up If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If End Try End If End Sub 'Page_Load End Class 'CH12ImageFromDatabaseVB End Namespace Example 12-12. Reading images from a database code-behind (.cs) //---------------------------------------------------------------------------- // // Module Name: CH12ImageFromDatabaseCS.aspx.cs // // Description: This module provides the code behind for the // CH12ImageFromDatabaseCS.aspx page // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; namespace ASPNetCookbook.CSExamples { public class CH12ImageFromDatabaseCS : System.Web.UI.Page { // constants used to create URLs to this page public const String PAGE_NAME = "CH12ImageFromDatabaseCS.aspx"; public const String QS_IMAGE_ID = "ImageID"; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { OleDbConnection dbConn = null; OleDbCommand dCmd = null; byte[] imageData = null; String strConnection = null; String strSQL = null; String imageID = null; if (!Page.IsPostBack) { try { // get the ID of the image to retrieve from the database imageID = Request.QueryString[QS_IMAGE_ID]; // get the connection string from web.config and open a connection // to the database strConnection = ConfigurationSettings.AppSettings["dbConnectionString"]; dbConn = new OleDbConnection(strConnection); dbConn.Open( ); // build the query string and get the data from the database strSQL = "SELECT ImageData " + "FROM BookImage " + "WHERE BookImageID=?"; dCmd = new OleDbCommand(strSQL, dbConn); dCmd.Parameters.Add(new OleDbParameter("BookImageID", imageID)); imageData = (byte[])(dCmd.ExecuteScalar( )); // set the content type for the image and write it to the response Response.ContentType = "image/gif"; Response.BinaryWrite(imageData); } finally { // clean up if (dbConn != null) { dbConn.Close( ); } } } } // Page_Load } // CH12ImageFromDatabaseCS } Example 12-13. Displaying images from a database (.aspx) <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH12TestImageFromDatabaseVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH12TestImageFromDatabaseVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Test Image From Database</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmTestImageDB" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td align="center"> </td> </tr> <tr> <td align="center" class="PageHeading"> Display Image From Database (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <table> <tr> <td> <asp:DropDownList ID="ddImages" Runat="server" /> </td> <td> <input id="btnViewImage" runat="server" type="button" value="View"> </td> </tr> <tr> <td id="tdSelectedImage" runat="server" colspan="2" align="center" class="SubHeading"> <br /><br /> Selected Image<br /><br /> <img id="imgBook" runat="server" border="0"> </td> </tr> </table> </td> </tr> </table> </form> </body> </html> Example 12-14. Displaying images from a database code-behind (.vb) Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH12TestImageFromDatabaseVB.aspx.vb ' ' Description: This module provides the code behind for the ' CH12TestImageFromDatabaseVB.aspx page. ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Configuration Imports System.Data Imports System.Data.OleDb Namespace ASPNetCookbook.VBExamples Public Class CH12TestImageFromDatabaseVB Inherits System.Web.UI.Page 'controls on the form Protected ddImages As System.Web.UI.WebControls.DropDownList Protected WithEvents btnViewImage As System.Web.UI.HtmlControls.HtmlInputButton Protected imgBook As System.Web.UI.HtmlControls.HtmlImage Protected tdSelectedImage As System.Web.UI.HtmlControls.HtmlTableCell '*************************************************************************** ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '--------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim dbConn As OleDbConnection Dim dc As OleDbCommand Dim dr As OleDbDataReader Dim strConnection As String Dim strSQL As String If (Not Page.IsPostBack) Then 'initially hide the selected image since one is not selected tdSelectedImage.Visible = False Try 'get the connection string from web.config and open a connection 'to the database strConnection = _ ConfigurationSettings.AppSettings("dbConnectionString") dbConn = New OleDb.OleDbConnection(strConnection) dbConn.Open( ) 'build the query string and get the data from the database strSQL = "SELECT BookImageID, Title " & _ "FROM BookImage" dc = New OleDbCommand(strSQL, dbConn) dr = dc.ExecuteReader( ) 'set the source of the data for the repeater control and bind it ddImages.DataSource = dr ddImages.DataTextField = "Title" ddImages.DataValueField = "BookImageID" ddImages.DataBind( ) Finally 'clean up If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If End Try End If End Sub 'Page_Load '*************************************************************************** ' ' ROUTINE: btnViewImage_ServerClick ' ' DESCRIPTION: This routine provides the event handler for the view ' image click event. It is responsible for setting the ' src attibute of the imgBook tag to the page that will ' retrieve the image data from the database and stream ' it to the browser. '--------------------------------------------------------------------------- Private Sub btnViewImage_ServerClick(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnViewImage.ServerClick 'set the source for the selected image tag imgBook.Src = CH12ImageFromDatabaseVB.PAGE_NAME & "?" & _ CH12ImageFromDatabaseVB.QS_IMAGE_ID & "=" & _ ddImages.SelectedItem.Value.ToString( ) 'make the selected image visible tdSelectedImage.Visible = True End Sub 'btnViewImage_ServerClick End Class 'CH12TestImageFromDatabaseVB End Namespace Example 12-15. Displaying images from a database code-behind (.cs) //---------------------------------------------------------------------------- // // Module Name: CH12TestImageFromDatabaseCS.aspx.cs // // Description: This module provides the code behind for the // CH12TestImageFromDatabaseCS.aspx page // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; namespace ASPNetCookbook.CSExamples { public class CH12TestImageFromDatabaseCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.WebControls.DropDownList ddImages; protected System.Web.UI.HtmlControls.HtmlInputButton btnViewImage; protected System.Web.UI.HtmlControls.HtmlImage imgBook; protected System.Web.UI.HtmlControls.HtmlTableCell tdSelectedImage; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { OleDbConnection dbConn = null; OleDbCommand dc = null; OleDbDataReader dr = null; String strConnection = null; String strSQL = null; // wire the view button click event this.btnViewImage.ServerClick += new EventHandler(this.btnViewImage_ServerClick); if (!Page.IsPostBack) { // initially hide the selected image since one is not selected tdSelectedImage.Visible = false; try { // get the connection string from web.config and open a connection // to the database strConnection = ConfigurationSettings.AppSettings["dbConnectionString"]; dbConn = new OleDbConnection(strConnection); dbConn.Open( ); // build the query string and get the data from the database strSQL = "SELECT BookImageID, Title " + "FROM BookImage"; dc = new OleDbCommand(strSQL, dbConn); dr = dc.ExecuteReader( ); // set the source of the data for the repeater control and bind it ddImages.DataSource = dr; ddImages.DataTextField = "Title"; ddImages.DataValueField = "BookImageID"; ddImages.DataBind( ); } finally { // clean up if (dbConn != null) { dbConn.Close( ); } } } } // Page_Load //************************************************************************ // // ROUTINE: btnViewImage_ServerClick // // DESCRIPTION: This routine provides the event handler for the view // image click event. It is responsible for setting the // src attibute of the imgBook tag to the page that will // retrieve the image data from the database and stream // it to the browser. //------------------------------------------------------------------------ private void btnViewImage_ServerClick(Object sender, System.EventArgs e) { // set the source for the selected image tag imgBook.Src = CH12ImageFromDatabaseCS.PAGE_NAME + "?" + CH12ImageFromDatabaseCS.QS_IMAGE_ID + "=" + ddImages.SelectedItem.Value.ToString( ); // make the selected image visible tdSelectedImage.Visible = true; } // btnViewImage_ServerClick } // CH12TestImageFromDatabaseCS } |