1.18. Displaying a Pop-Up Details Window

Problem

You want to provide additional details for each row in a DataGrid using a pop-up window.

Solution

Add a Details button to each row in the Datagrid. When the user clicks the button, open a new browser window, obtain the information from the server, and then display the detailed information in a pop-up window. An example of the output that is possible with this approach is shown in Figure 1-22 (sample DataGrid) and Figure 1-23 (sample pop-up window output). As with the other recipes in this book, we’ve implemented a complete application that illustrates this approach. The form and code-behind for the page containing the sample DataGrid is shown in Example 1-51 through Example 1-53, and the form and code-behind for the sample pop-up window is shown in Example 1-54 through Example 1-56.

DataGrid with pop-up details window output

Figure 1-22. DataGrid with pop-up details window output

Pop-up details window output

Figure 1-23. Pop-up details window output

Discussion

To implement this solution, create a DataGrid in the normal fashion, but add a link button column to display a Details link. The idea is that when the user clicks the Details link within a row of the DataGrid, the browser opens a new window and requests the appropriate page from the server. In the context of our example that implements this solution, a book details page is requested. From here on, the recipe’s remaining steps are described in the context of our example because we use techniques that you are likely to find helpful in implementing your own application.

In our example, when the book details page is processed, a book ID is extracted from the query string and is then used in the database query to get the detailed data for the specific book, as shown in the setupForm method of Example 1-55 (VB) and Example 1-56 (C#).

When building a Details link in the .aspx file, an HTML anchor tag is placed in the ItemTemplate for the column. (The purpose of the anchor tag is to request the details page when the associated link button is clicked.) The target property of the HTML anchor is set to "_blank“, causing a new browser window to open when the link is clicked.

The Page_Load method in the code-behind is nearly identical to that used in other recipes, with only one small change. The line of code shown next is added to populate the DataKeys collection of the DataGrid with the primary key values for the rows being displayed. This causes the DataGrid to keep track of the primary key value for each row without our having to output the data in a hidden column. These values are needed later to display the book details.

               Discussion
dgBooks.DataKeyField = "BookID" 

Discussion
dgBooks.DataKeyField = "BookID";

The DataGrid control’s ItemDataBound event is used to set the href value for the “details” HTML anchors added to the DataGrid. Because this event is called independently for every row in the DataGrid, the item type must be checked to see if this event applies for a given data row.

When the event does apply to a data row, the first thing we must do is get the ID of the book being displayed in the row, as shown here:

               Discussion
bookID = CInt(dgBooks.DataKeys(e.Item.ItemIndex))

Discussion
bookID = (int)(dgBooks.DataKeys[e.Item.ItemIndex]);

Next, we need to get a reference to the “details” HTML anchor in the row. Because ItemTemplates were used and the anchor controls in the templates were given IDs, we can accomplish this by using the FindControl method of the passed item. If a standard BoundColumn were used instead, the data would have to be accessed using the cells collection (e.g., e.Item.Cells(1).controls(1) would access the anchor control in this example). Providing an ID and using FindControl eliminates the potential for broken code if the columns are later reordered. Note that the control must be cast to an HTMLAnchor because the controls collection is a collection of objects.

After obtaining a reference to the HTML anchor tag, we need to set the href property of the anchor to the name of the details page. In addition, the URL needs to include "BookID = n" where n is the ID of the book displayed in the row. The resulting anchor tag in the DataGrid for BookID = 1 is shown here:

<a href="/ASPNetCookbook/VBExamples/BookDetails.aspx?BookID=1" 
   id="dgBooks_  _ctl3_lnkDetails" target="_blank">

Tip

The ID is altered by ASP.NET to ensure all server controls have unique IDs. ASP.NET maintains both the original ID and the unique ID, so the original ID we provided with the FindControl method is handled correctly, sparing us from having to figure out the unique ID or dealing with indexing into items and cells.

Example 1-51. DataGrid with pop-up details window (.aspx)

<%@ Page Language="vb" AutoEventWireup="false" 
         Codebehind="CH01DatagridWithPopupDetailsVB.aspx.vb" 
         Inherits="ASPNetCookbook.VBExamples.CH01DatagridWithPopupDetailsVB" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>DataGrid With Popup Details</title>
    <link rel="stylesheet" href="css/ASPNetCookbook.css">
  </head>
  <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
    <form id="frmDatagrid" 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><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center" class="PageHeading">
            DataGrid With Popup Details (VB)
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <asp:DataGrid 
                                id="dgBooks" 
                                runat="server" 
                                BorderColor="000080" 
                                BorderWidth="2px"
                                AutoGenerateColumns="False"
                                width="100%">

                                <HeaderStyle 
                                  HorizontalAlign="Center" 
                                  ForeColor="#FFFFFF" 
                                  BackColor="#000080" 
                                  Font-Bold=true
                                  CssClass="TableHeader" /> 

                                <ItemStyle
                                  BackColor="#FFFFE0" 
                                  cssClass="TableCellNormal" />

                                <AlternatingItemStyle 
                                  BackColor="#FFFFFF" 
                                  cssClass="TableCellAlternating" />
                                

                                <Columns>
                                  <asp:BoundColumn HeaderText="Title" DataField="Title" />
                                  <asp:TemplateColumn ItemStyle-HorizontalAlign="Center">
                                    <ItemTemplate>
                                      <a id="lnkDetails" runat="server" 
                                             target="_blank">Details</a>
                                    </ItemTemplate>
                                  </asp:TemplateColumn>
                                </Columns>
                              </asp:DataGrid>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Example 1-52. DataGrid with pop-up details window code-behind (.vb)

Option Explicit On 
Option Strict On
'-----------------------------------------------------------------------------
'
'   Module Name: CH01DatagridWithPopupDetailsVB.aspx.vb
'
'   Description: This class provides the code behind for
'                CH01DatagridWithPopupDetailsVB
'
'*****************************************************************************
Imports Microsoft.VisualBasic
Imports System
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls

Namespace ASPNetCookbook.VBExamples
  Public Class CH01DatagridWithPopupDetailsVB
    Inherits System.Web.UI.Page

    'controls on form
    Protected WithEvents dgBooks As System.Web.UI.WebControls.DataGrid

    '*************************************************************************
    '
    '   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 da As OleDbDataAdapter
      Dim ds As DataSet
      Dim strConnection As String
      Dim strSQL As String

      If (Not Page.IsPostBack) Then
        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 BookID, Title " & _
                   "FROM Book " & _
                   "ORDER BY Title"

          da = New OleDbDataAdapter(strSQL, dbConn)
          ds = New DataSet
          da.Fill(ds)

          'set the source of the data for the datagrid control and bind it
          dgBooks.DataKeyField = "BookID"

          dgBooks.DataSource = ds
          dgBooks.DataBind( )

        Finally
          'cleanup
          If (Not IsNothing(dbConn)) Then
            dbConn.Close( )
          End If
        End Try
      End If
    End Sub  'Page_Load

    '*************************************************************************
    '
    '   ROUTINE: dgBooks_ItemDataBound
    '
    '   DESCRIPTION: This routine is the event handler that is called for each 
    '                item in the datagrid after a data bind occurs.  It is 
    '                responsible for setting the URL of the anchor tags to the
    '                page used to display the details for a book
    '-------------------------------------------------------------------------
    Private Sub dgBooks_ItemDataBound(ByVal sender As Object, _
                                  ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _
                              Handles dgBooks.ItemDataBound

                        Const DETAIL_PAGE As String = "CH01BookDetailsVB.aspx"

                        Dim bookID As Integer
                        Dim anchor As HtmlAnchor

                        'check the type of item that was databound and only take action if it 
                        'was a row in the datagrid
                        If ((e.Item.ItemType = ListItemType.Pager) Or _
                            (e.Item.ItemType = ListItemType.Header) Or _
                            (e.Item.ItemType = ListItemType.Footer)) Then
                          'do nothing
                        Else
                          'the item that was bound is an "Item", "AlternatingItem", "EditItem", 
                          '"SelectedItem" or "Separator" (in other words a row) 
                          bookID = CInt(dgBooks.DataKeys(e.Item.ItemIndex))

                          'get the anchor tag in the row
                          'NOTE: This can be done by using the FindControl method of the passed
                          '      item because ItemTemplates were used and the anchor controls in 
                          '      the templates where given IDs.  If a standard BoundColumn was 
                          '      used, the data would have to be accessed using the cells 
                          '      collection (e.g. e.Item.Cells(1).controls(1) would access the 
                          '      anchor control in this example.
                          anchor = CType(e.Item.FindControl("lnkDetails"), _
                                         HtmlAnchor)
                          'set the URL of the anchor tag to the page used to display the book
                          'details passing the ID of the book in the querystring
                          anchor.HRef = DETAIL_PAGE & "?BookID=" & bookID.ToString( )
                        End If

                      End Sub  'dgBooks_ItemDataBound
  End Class  'CH01DatagridWithPopupDetailsVB
End Namespace

Example 1-53. DataGrid with pop-up details window code-behind (.cs)

//----------------------------------------------------------------------------
//
//   Module Name: CH01DatagridWithPopupDetailsCS.aspx.cs
//
//   Description: This class provides the code behind for
//                CH01DatagridWithPopupDetailsCS.aspx
//
//****************************************************************************
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace ASPNetCookbook.CSExamples
{
  public class CH01DatagridWithPopupDetailsCS : System.Web.UI.Page
  {
    // controls on form
    protected System.Web.UI.WebControls.DataGrid dgBooks;

    //************************************************************************
    //
    //   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;
      OleDbDataAdapter da = null;
      DataSet ds = null;
      String strConnection = null;
      String strSQL =null;

      // wire the item data bound event
      this.dgBooks.ItemDataBound +=
        new DataGridItemEventHandler(this.dgBooks_ItemDataBound);

      if (!Page.IsPostBack)
      {
        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 BookID, Title " +
                   "FROM Book " +
                   "ORDER BY Title";
          da = new OleDbDataAdapter(strSQL, dbConn);
          ds = new DataSet( );
          da.Fill(ds);

          // set the source of the data for the datagrid control and bind it
          dgBooks.DataKeyField = "BookID";
          dgBooks.DataSource = ds;
          dgBooks.DataBind( );
        }  // try

        finally
        {
          // clean up
          if (dbConn != null)
          {
            dbConn.Close( );
          }
        }  // finally
      }
    }  // Page_Load

    //************************************************************************
    //
    //   ROUTINE: dgBooks_ItemDataBound
    //
    //   DESCRIPTION: This routine is the event handler that is called for each
    //                item in the datagrid after a data bind occurs.  It is
    //                responsible for setting the URL of the anchor tags to the
    //                page used to display the details for a book
    //
    //------------------------------------------------------------------------
    private void dgBooks_ItemDataBound(Object sender,
                        System.Web.UI.WebControls.DataGridItemEventArgs e)
                      {
                        const String DETAIL_PAGE = "CH01BookDetailsCS.aspx";
                        int bookID;
                        HtmlAnchor anchor = null;

                        // check the type of item that was databound and only take action if it
                        // was a row in the datagrid
                        if ((e.Item.ItemType == ListItemType.Pager) ||
                            (e.Item.ItemType == ListItemType.Header) ||
                            (e.Item.ItemType == ListItemType.Footer))
                        {
                          // do nothing
                        }
                        else
                        {
                          // the item that was bound is an "Item", "AlternatingItem",
                          // "EditItem", "SelectedItem" or "Separator" (in other words a row)
                          bookID = (int)(dgBooks.DataKeys[e.Item.ItemIndex]);
                          // get the anchor tag in the row
                          // NOTE: This can be done by using the FindControl method of the
                          //       passeditem because ItemTemplates were used and the anchor
                          //       controls in the templates where given IDs.  If a standard
                          //       BoundColumn was used, the data would have to be accessed
                          //       using the cells collection (e.g. e.Item.Cells(1).controls(1)
                          //       would access the anchor control in this example.
                          anchor = (HtmlAnchor)(e.Item.FindControl("lnkDetails"));

                          // set the URL of the anchor tag to the page used to display the book
                          // details passing the ID of the book in the querystring
                          anchor.HRef = DETAIL_PAGE + "?BookID=" + bookID.ToString( );
                        }
                      }  // dgBooks_ItemDataBound
  }  // CH01DatagridWithPopupDetailsCS
}

Example 1-54. Pop-up detail page (.aspx)

<%@ Page Language="vb" AutoEventWireup="false" 
         Codebehind="CH01BookDetailsVB.aspx.vb" 
         Inherits="ASPNetCookbook.VBExamples.CH01BookDetailsVB" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>Book Details</title>
    <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
    <meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
    <meta name=vs_defaultClientScript content="JavaScript">
    <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
    <link rel="stylesheet" href="css/ASPNetCookbook.css">
  </head>
  <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
    <form id="frmDatagrid" 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><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center" class="PageHeading">
            Book Details (VB)
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <!-- Put book details here -->
            <table width="600" border="0">
              <tr>
                <td rowspan="6" align="center" width="250">
                  <img id="imgBook" runat="server"></td>
                <td class="TableCellNormal" width="150">Title: </td>
                <td id="bookTitle" runat="server" 
                    class="TableCellNormal" width="325"></td>                
              </tr>
              <tr>
                <td class="TableCellNormal">ISBN: </td>
                <td id="isbn" runat="server" 
                    class="TableCellNormal"></td>
              </tr>
              <tr>
                <td class="TableCellNormal">Publisher: </td>
                <td id="publisher" runat="server" 
                    class="TableCellNormal"></td>
              </tr>
              <tr>
                <td class="TableCellNormal">Publish Date: </td>
                <td id="publishDate" runat="server" 
                    class="TableCellNormal"></td>
              </tr>
              <tr>
                <td class="TableCellNormal">List Price: </td>
                <td id="listPrice" runat="server" 
                    class="TableCellNormal"></td>
              </tr>
              <tr>
                <td class="TableCellNormal">Discounted Price: </td>
                <td id="discountedPrice" runat="server" 
                    class="TableCellNormal"></td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Example 1-55. Pop-up detail page code-behind (.vb)

Option Explicit On 
Option Strict On
'-----------------------------------------------------------------------------
'
'   Module Name: CH01BookDetailsVB.aspx.vb
'
'   Description: This class provides the code behind for 
'                CH01BookDetailsVB.aspx
'
'*****************************************************************************
Imports Microsoft.VisualBasic
Imports System
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb

Namespace ASPNetCookbook.VBExamples
  Public Class CH01BookDetailsVB
    Inherits System.Web.UI.Page

    'controls on form
    Protected imgBook As System.Web.UI.HtmlControls.HtmlImage
    Protected bookTitle As System.Web.UI.HtmlControls.HtmlTableCell
    Protected isbn As System.Web.UI.HtmlControls.HtmlTableCell
    Protected publisher As System.Web.UI.HtmlControls.HtmlTableCell
    Protected publishDate As System.Web.UI.HtmlControls.HtmlTableCell
    Protected listPrice As System.Web.UI.HtmlControls.HtmlTableCell
    Protected discountedPrice 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 dCmd As OleDbCommand
      Dim dReader As OleDbDataReader
      Dim strConnection As String
      Dim strSQL As String
      Dim bookID As String

      If (Not Page.IsPostBack) Then
        Try
          'get the book ID from the querystring in the URL
                            If (IsNothing(Request.QueryString.Item("BookID"))) Then
                              'production code needs to handle the page request without the needed
                              'information in the querystring here
                            Else
                              bookID = Request.QueryString.Item("BookID").ToString( )

                              '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 Title, ISBN, Publisher, PublishDate, " & _
                                       "ListPrice, DiscountedPrice, ImageFilename " & _
                                       "FROM Book " & _
                                       "WHERE BookID=?"

                              dCmd = New OleDbCommand(strSQL, dbConn)
                              dCmd.Parameters.Add(New OleDbParameter("BookID", bookID))
                              dReader = dCmd.ExecuteReader( )

                              If (dReader.Read) Then
                                'set the data in the individual controls on the page
                                imgBook.Src = "images/books/" & _
                                              dReader.Item("ImageFilename").ToString( )
                                bookTitle.InnerText = dReader.Item("Title").ToString( )
                                isbn.InnerText = dReader.Item("ISBN").ToString( )
                                publisher.InnerText = dReader.Item("Publisher").ToString( )
                                publishDate.InnerText = Format(dReader.Item("PublishDate"), _
                                                               "MMM dd, yyyy")
                                listPrice.InnerText = Format(dReader.Item("ListPrice"), _
                                                             "C2")
                           discountedPrice.InnerText = Format(dReader.Item("DiscountedPrice"), _
                                                              "C2")
                              End If
          End If

        Finally
          'cleanup
          If (Not IsNothing(dReader)) Then
            dReader.Close( )
          End If

          If (Not IsNothing(dbConn)) Then
            dbConn.Close( )
          End If
        End Try
      End If
    End Sub  'Page_Load

  End Class  'CH01BookDetailsVB
End Namespace

Example 1-56. Pop-up detail page code-behind (.cs)

//----------------------------------------------------------------------------
//
//   Module Name: CH01BookDetailsCS.aspx.cs
//
//   Description: This class provides the code behind for
//                CH01BookDetailsCS.aspx
//
//****************************************************************************
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;

namespace ASPNetCookbook.CSExamples
{
  public class CH01BookDetailsCS : System.Web.UI.Page
  {
    // controls on form
    protected System.Web.UI.HtmlControls.HtmlImage imgBook;
    protected System.Web.UI.HtmlControls.HtmlTableCell bookTitle ;
    protected System.Web.UI.HtmlControls.HtmlTableCell isbn;
    protected System.Web.UI.HtmlControls.HtmlTableCell publisher;
    protected System.Web.UI.HtmlControls.HtmlTableCell publishDate;
    protected System.Web.UI.HtmlControls.HtmlTableCell listPrice;
    protected System.Web.UI.HtmlControls.HtmlTableCell discountedPrice;

    //************************************************************************
    //
    //   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;
      OleDbDataReader dReader = null;
      String strConnection = null;
      String strSQL = null;
      String bookID = null;
      DateTime pubDate;
      Decimal price;

      if (!Page.IsPostBack)
      {
        try
        {
          // get the book ID from the querystring in the URL
                            if (Request.QueryString["BookID"] == null)
                            {
                              // production code needs to handle the page request without the 
                              // needed information in the querystring here
                            }
                            else
                            {
                              bookID = Request.QueryString["BookID"].ToString( );

                              // 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 Title, ISBN, Publisher, PublishDate, " +
                                       "ListPrice, DiscountedPrice, ImageFilename " +
                                       "FROM Book " +
                                       "WHERE BookID=?";

                              dCmd = new OleDbCommand(strSQL, dbConn);
                              dCmd.Parameters.Add(new OleDbParameter("BookID", bookID));
                              dReader = dCmd.ExecuteReader( );

                              if (dReader.Read( ))
                              {
                                // set the data in the individual controls on the page
                                imgBook.Src = "images/books/" +
                                              dReader["ImageFilename"].ToString( );
                                bookTitle.InnerText = dReader["Title"].ToString( );
                                isbn.InnerText = dReader["ISBN"].ToString( );
                                publisher.InnerText = dReader["Publisher"].ToString( );
                                pubDate = (DateTime)dReader["PublishDate"];
                                publishDate.InnerText = pubDate.ToString("MMM dd, yyyy");
                                price = (Decimal)dReader["ListPrice"];
                                listPrice.InnerText = price.ToString("C2");

                                price = (Decimal)dReader["DiscountedPrice"];
                                discountedPrice.InnerText = price.ToString("C2");
                              }
                            }
        }  // try

        finally
        {
          // clean up
          if (dReader != null)
          {
            dReader.Close( );
          }

          if (dbConn != null)
          {
            dbConn.Close( );
          }
        }  // finally
      }
    }  // Page_Load
  }  // CH01BookDetailsCS
}

Get ASP.NET Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.