ASPX Pages

Now that there exists two UserControls, it is time to create some aspx pages to host those controls. The first page to implement is the EmployeeEdit page. This allows the EmployeeViewPaglet control to navigate to an edit page. The edit page should allow for changes to the name, department, and to upload a photograph. ASP.NET makes client-side file transfer a snap.

EmployeeEdit

One of the requirements for the EmployeeBrowser site was the ability to edit employee information and the associated photograph. Rather than build another UserControl, this functionality will be implemented within the context of an aspx page. The only reason for doing so is to poke around ASP.NET. The EmployeeEdit page would be a good candidate for a UserControl; I'll leave that to you.

There's no real magic to the layout, so the markup will be omitted from the text. Only new or interesting markup will be shown. The full code is contained on the CD-ROM included with this book, and you should refer to it if needed. Figure 4.3.4 shows the EmployeeEdit page with a record ready to edit.

Figure 4.3.4. EmployeeEdit page.


The first control to look at is the drop-down list used to hold the names of the various departments. In standard HTML, it was necessary to hard-code the values for list boxes or drop-down menus. You could use script woven in to produce some type of data dependant list, but this fails in comparison to ASP.NET and databinding. Listing 4.3.6 shows the declaration for an asp:dropdownlist which will be bound to a variable within the EmployeeEdit.cs source code.

Listing 4.3.6. dropdownlist Snipit from EmployeEdit.aspx
1: <tr>
2:   <td>Department</td>
3:   <td>
4:       <asp:dropdownlist runat="Server" id="Departments" />
5:   </td>
6: </tr>

Listing 4.3.6 comes from the EmployeeEdit.aspx page. Although there seems to be nothing worth noting, don't overlook the fact that the dropdownlist does not define any listitems. Instead of declaring the listitems within the aspx page, each ASP.NET WebControl supports databinding similar to the Windows Forms controls. In the code supporting the EmployeeEdit aspx page, there will exist the code to set up the databinding for the control. As with any databinding source, the container must implement GetEnumerator() or the IEnumerable interface. The departments will be held within an array list, so the general code looks something like the following:

ArrayList Depts = new ArrayList( );
FillDepts( Depts );
Departments.DataSource = Depts;
Departments.DataBind( );

Setting a databound control really doesn't require a lot of effort on the developer's part. Of course, like any WebControl, pragmatic access is always an option. If the default databinding doesn't fit the bill, there is the ability to write C# code and take full control.

The next control of interest is the input control that has its type set to file. This allows for the user to browse for a new photograph and upload it to the Web server.

<input type="file" id="EmpImageFile" name="EmpImageFile" runat="server">

Wait, this is not an asp:* type control, so how can it be accessed behind the scenes? It just so happens that ASP.NET supports binding of HTML controls just like WebControls. When the input tag is specified with type="file", the designer will create a variable of the following type:

System.Web.UI.HtmlControls.HtmlInputFile

This allows the code page to again access the HTML element. Listing 4.3.7 shows the C# code for EmployeeEdit.aspx.cs.

Listing 4.3.7. EmployeeEdit.aspx.cs
  1: using System;
  2: using System.Collections;
  3: using System.ComponentModel;
  4: using System.Data;
  5: using System.Data.SqlClient;
  6: using System.Drawing;
  7: using System.Web;
  8: using System.Web.SessionState;
  9: using System.Web.UI;
 10: using System.Web.UI.WebControls;
 11: using System.Web.UI.HtmlControls;
 12:
 13: using Stingray.Data;
 14:
 15: namespace EmployeeBrowser
 16: {
 17:     /// <summary>
 18:     /// Summary description for EmployeeEdit.
 19:     /// </summary>
 20:     public class EmployeeEdit : System.Web.UI.Page
 21:     {
 22:         protected System.Web.UI.WebControls.Image EmployeeImage;
 23:         protected System.Web.UI.WebControls.Label EmployeeId;
 24:         protected System.Web.UI.WebControls.TextBox FirstName;
 25:         protected System.Web.UI.WebControls.TextBox LastName;
 26:         protected System.Web.UI.WebControls.DropDownList Departments;
 27:         protected System.Web.UI.WebControls.Button btnUpdate;
 28:         protected System.Web.UI.HtmlControls.HtmlInputFile EmpImageFile;
 29:
 30:         public EmployeeEdit()
 31:         {
 32:             Page.Init += new System.EventHandler(Page_Init);
 33:         }
 34:
 35:         private void Page_Load(object sender, System.EventArgs e)
 36:         {
 37:            // Put user code to initialize the page here
 38:
 39:            //Enable Data binding
 40:            DataBind( );
 41:
 42:            if( !IsPostBack )
 43:                PopulateForm( );
 44:            else
 45:                UpdateEmployee( );
 46:         }
 47:
 48:         private void PopulateForm( )
 49:         {
 50:
 51:             string EmpId = this.Request.QueryString["EmpId"].ToString( );
 52:             SqlConnection dbCon = DBAccess.AcquireConnection( );
 53:             SqlDataAdapter cmd = new SqlDataAdapter(string.Format("SELECT * FROM
 EMPLOYEE WHERE EMP_ID = { 0} ", EmpId),dbCon);
 54:             DataSet dsResult = new DataSet( );
 55:             Employee emp = new Employee( );
 56:
 57:             cmd.Fill( dsResult, "EMPLOYEE" );
 58:             if( dsResult.Tables["EMPLOYEE"] != null)
 59:                 emp.FromDataRow( dsResult.Tables["EMPLOYEE"].Rows[0] );
 60:
 61:             //Set the values for stuff
 62:             this.EmployeeId.Text = emp.Id;
 63:             this.FirstName.Text = emp.FirstName;
 64:             this.LastName.Text  = emp.LastName;
 65:             this.EmployeeImage.ImageUrl =
 66:             string.Format("~/images/employees/{ 0} .jpg", emp.PictureId.ToString( ));
 67:
 68:             //Populate the Department list
 69:             cmd.SelectCommand.CommandText = "SELECT * FROM DEPARTMENT";
 70:             cmd.Fill( dsResult, "DEPARTMENT" );
 71:             Hashtable ht = new Hashtable( );
 72:
 73:             foreach( DataRow row in dsResult.Tables["DEPARTMENT"].Rows)
 74:             {
 75:                 int nValue = (int)row["DEPT_ID"];
 76:                 string Name = (string)row["NAME"];
 77:                 ht.Add( Name, nValue );
 78:                 this.Departments.Items.Add( Name );
 79:             }
 80:
 81:             this.Session["DEPT_MAPPING"] = ht;
 82:             this.Session["CACHE:EMP"] = emp;        //save the employee
 83:
 84:          }
 85:
 86:          private void UpdateEmployee( )
 87:          {
 88:
 89:              Employee emp = (Employee)Session["CACHE:EMP"];
 90:
 91:              emp.FirstName = this.FirstName.Text;
 92:              emp.LastName = this.LastName.Text;
 93:
 94:
 95:              //get new department
 96:              Hashtable ht = (Hashtable)Session["DEPT_MAPPING"];
 97:              int DeptId = (int)ht[ this.Departments.SelectedItem.Text ];
 98:              emp.DeptId = DeptId;
 99:
100:
101:
102:              //Get the Photo
103:              if( this.EmpImageFile.PostedFile != null &&
104:                  this.EmpImageFile.PostedFile.FileName.Length > 0 )
105:              {
106:
107:                  //Remove the Old Photo
108:                  string strFileName =
109:                             string.Format(
110:         "C:/Inetpub/wwwroot/EmployeeBrowser/images/employees/{ 0} .jpg",
111:         emp.PictureId.ToString( )
112:                             );
113:
114:                  System.IO.File.Delete( strFileName );
115:
116:                  emp.PictureId =  System.Guid.NewGuid( );
117:                  strFileName =
118:                       string.Format(
119:         "C:/Inetpub/wwwroot/EmployeeBrowser/images/employees/{ 0} .jpg",
120:         emp.PictureId.ToString( )
121:                                    );
122:
123:                      this.EmpImageFile.PostedFile.SaveAs( strFileName );
124:               }
125:
126:               //Update the Employee
127:               DBAccess.Save( DBAccess.AcquireConnection( ), emp );
128:
129:                  string strUrl =
130:                         string.Format(
131:            "EmployeeListing.aspx?DeptId={ 0} &FirstName={ 1} &LastName={ 2} ",
132:                          emp.DeptId,emp.FirstName,emp.LastName
133:                         );
134:
135:                  Response.Redirect( strUrl );
136:
137:            }
138:
139:            private void Page_Init(object sender, EventArgs e)
140:            {
141:                //
142:                // CODEGEN: This call is required by the ASP.NET Web Form Designer.
143:                //
144:                InitializeComponent();
145:            }
146:
147:            #region Web Form Designer generated code
148:            /// <summary>
149:            /// Required method for Designer support - do not modify
150:            /// the contents of this method with the code editor.
151:            /// </summary>
152:            private void InitializeComponent()
153:            {
154:                this.Load += new System.EventHandler(this.Page_Load);
155:
156:            }
157:            #endregion
158:     }
159: }

The EmployeeEdit page was designed to accept a query string containing the Employee ID as EmpId; recall the EmployeeViewPagelet and the code contained within the OnEdit_Click method.

The following lines are from Listing 4.3.5:

113: protected void OnEdit_Click( object sender, EventArgs e )
114: {
115:       Response.Redirect(
116:               string.Format( "~/EmployeeEdit.aspx?EmpId={ 0} ",
117:                               btnEdit.CommandArgument )
118:                );
119: }

When the Edit button raises a click event, the CommandArgument property contains the Employee ID. This Employee ID is used to create an HTTP GET request. Line 115 shows the syntax for passing parameters from one page to another.

The PopulateForm method, found in Listing 4.3.7, accesses the QueryString collection found in the Request object. I've omitted error checking and redirection to an error page, but you get the idea. The Employee ID contains all the state information necessary to populate the controls found within the page.

To hold on to information, such as state information or objects, there are two options—Session or Cache. The EmployeeEdit page makes use of the session to store any necessary data. A Session can survive IIS crashes and work process restarts, but the Cache does not. When deciding where information should be stored, you'll need to examine the uses of the data and the necessity of ensuring that the data exists.

The Session and Cache objects both contain a hash table that maps a key to the object you want to store. The EmployeeEdit page stores both a hash table and the employee within the Session.

When the Update button raises a click event, the page is reloaded with IsPostBack set to true. Page_Load tests for this condition and calls UpdateEmployee rather than PopulateForm.

EmployeeListing

The EmployeeBrowser Web application is starting to come together. With the basic HeaderContol, EmployeeView control, and the EmployeeEdit page complete, it's time to create a Listings page. The Listings page will host one or more EmployeeView controls and allow for paging back and forth through the various employees.

Figure 4.3.5 shows the basic listing control with 2 rows per screen. Also notice the Next >> button at the bottom of the form. When paging takes place, the EmployeeListing.aspx will determine if there are previous records, and display a << Prev button when appropriate, as shown in Figure 4.3.5. The same is true for the Next >> button. If there are additional records, it will be visible; if not, the Next >> button will be hidden.

Figure 4.3.5. EmployeeListing with two rows.


As you can see, I didn't enforce any type of sizing constraint on the images. The simplest way, of course, is to specify the allowed image size and reject any image that does not fit the sizing criteria.

So how does the EmployeeListing page display the EmployeeViewPagelets? Easy. The secret is to make use of the asp:repeater control. Remember the repeater control we discussed? The EmployeeListing makes use of the repeater control to display the appropriate number of employees per page. Listing 4.3.8 shows the binding for the EmployeeView control.

Figure 4.3.6. EmployeeListing with two rows and the Prev button enabled.


Listing 4.3.8. Snippet from EmployeeListing.aspx
 1: <asp:repeater id="EmployeeRepeater" runat="server">
 2:   <ItemTemplate>
 3:     <tr>
 4:       <td>
 5:           <EmployeeBrowser:EmployeeViewControl runat="server"
 6:               EmployeeId='<%# DataBinder.Eval( Container.DataItem, "Id" )  %>'
 7:               FirstName='<%# DataBinder.Eval( Container.DataItem, "FirstName" )  %>'
 8:               LastName='<%# DataBinder.Eval( Container.DataItem, "LastName" )  %>'
 9:               PictureId='<%# DataBinder.Eval( Container.DataItem,"PictureId" ) %>'>
10:           </EmployeeBrowser:EmployeeViewControl>
11:       </td>
12:     </tr>
13:   </ItemTemplate>
14: </asp:repeater>

The EmployeeListing makes use of WebControl databinding to set the various properties of the EmployeeViewPagelet control. Notice that each property of the EmployeeViewPagelet control is assigned its value through the use of

DataBinder.Eval( Container.DataItem, X )

where X is the name of a field found with the datasource. The source code behind the page creates an ArrayList of Employee objects and binds that list to the repeater control, EmployeeRepeater. Using this technique, binding property values is a breeze! In fact, the snippet in Listing 4.3.8 is the only real meat of the aspx page. The rest is just HTML markup and the inclusion of the HeaderControl.

As with every aspx page so far, the EmployeeListing page implements the paging logic in a C# source file. After the data is bound to the repeater control, the current index is pushed on a stack and that stack is saved in the Session. When the Next or Prev buttons are pressed, the index is either calculated for the next set or the pervious index is popped of the stack. Listing 4.3.9 presents the source for the EmployeeListing page.

Listing 4.3.9. EmployeeListing.aspx.cs
  1: using System;
  2: using System.Collections;
  3: using System.ComponentModel;
  4: using System.Data;
  5: using System.Data.SqlClient;
  6: using System.Drawing;
  7: using System.Web;
  8: using System.Web.SessionState;
  9: using System.Web.UI;
 10: using System.Web.UI.WebControls;
 11: using System.Web.UI.HtmlControls;
 12:
 13: using Stingray.Data;
 14:
 15: namespace EmployeeBrowser
 16: {
 17:
 18:     class ViewerState
 19:     {
 20:         public static string VIEW_STATE_SESSION_KEY = "EMPLOYEE_VIEWER_STATE";
 21:         public DataSet       m_EmployeeCache;
 22:         public int           m_RowCount = 0;
 23:         public int           m_MaxPerPage = 5;
 24:         public int           m_CurrentIndex = 0;
 25:         public Stack         m_IdxStack = new Stack( );
 26:     }
 27:
 28:     /// <summary>
 29:     /// Summary description for EmployeeListing.
 30:     /// </summary>
 31:     public class EmployeeListing : System.Web.UI.Page
 32:     {
 33:         protected System.Web.UI.WebControls.Button    btnNext;
 34:         protected System.Web.UI.WebControls.Button    btnPrev;
 35:         protected System.Web.UI.WebControls.Repeater  EmployeeRepeater;
 36:         private ArrayList                             m_EmployeeList;
 37:         private ViewerState                           m_ViewerState;
 38:
 39:
 40:
 41:         public EmployeeListing()
 42:         {
 43:             Page.Init += new System.EventHandler(Page_Init);
 44:         }
 45:
 46:         private void Page_Load(object sender, System.EventArgs e)
 47:         {
 48:             if (!IsPostBack)
 49:             {
 50:
 51:                 int     DeptId = 0;
 52:                 string  FirstName;
 53:                 string  LastName;
 54:
 55:
 56:                 m_ViewerState = new ViewerState( );
 57:                 this.Session.Add(ViewerState.VIEW_STATE_SESSION_KEY ,m_ViewerState);
 58:
 59:                 GetParams( out FirstName, out LastName, ref DeptId,  ref
 m_ViewerState.m_MaxPerPage );
 60:
 61:                 LoadDataSet( FirstName, LastName, DeptId );
 62:
 63:
 64:                 //save current index
 65:                 m_ViewerState.m_IdxStack.Push( 0 );
 66:                 int Index = this.CalcNextIndex(  );
 67:                 m_ViewerState.m_CurrentIndex = Index;
 68:                 this.DisplayData( 0, m_ViewerState.m_CurrentIndex );
 69:                 UpdateNavigationButtons( );
 70:
 71:             }   else {
 72:
 73:                 m_ViewerState = (ViewerState)this.Session[ ViewerState
.VIEW_STATE_SESSION_KEY];
 74:             }
 75:
 76:         }
 77:
 78:         private void Page_Init(object sender, EventArgs e)
 79:         {
 80:            //
 81:            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
 82:            //
 83:            InitializeComponent();
 84:         }
 85:
 86:         protected void GetParams(out string FirstName, out string LastName, ref int
 DeptId, ref int MaxPerPage )
 87:         {
 88:             DeptId     = this.Request.QueryString["DeptId"] == null ?
 89:                          -1 : Int32.Parse(this.Request.QueryString["DeptId"].ToString
( ));
 90:
 91:             FirstName  = this.Request.QueryString["FirstName"] == null ?
 92:                          "" : this.Request.QueryString["FirstName"].ToString();
 93:
 94:             LastName   = this.Request.QueryString["LastName"] == null ?
 95:                          "" : this.Request.QueryString["LastName"].ToString();
 96:
 97:             MaxPerPage = this.Request.QueryString["MaxPerPage"] == null ?
 98:                          5 : Int32.Parse(this.Request.QueryString["MaxPerPage"]
.ToString( ));
 99:         }
100:
101:         protected void LoadDataSet(string FName, string LName, int DeptId)
102:         {
103:
104:             if( DeptId != -1 )
105:             {
106:                 m_ViewerState.m_EmployeeCache = Search.Find(DBAccess
.AcquireConnection( ), DeptId, FName, LName);
107:             }  else {
108:                 m_ViewerState.m_EmployeeCache = Search.Find(DBAccess
.AcquireConnection( ), FName, LName);
109:             }
110:
111:             m_ViewerState.m_RowCount = m_ViewerState.m_EmployeeCache
.Tables["EMPLOYEE"].Rows.Count;
112:         }
113:
114:
115:         protected void DisplayData( int StartIndex, int StopIndex )
116:         {
117:
118:             m_EmployeeList = new ArrayList( );
119:
120:             for(int i = StartIndex; i < StopIndex; i++)
121:             {
122:                 Employee e = new Employee( );
123:                 e.FromDataRow( m_ViewerState.m_EmployeeCache.Tables["EMPLOYEE"]
.Rows[i] );
124:                 m_EmployeeList.Add( e );
125:             }
126:
127:             //Bind the data
128:             EmployeeRepeater.DataSource= m_EmployeeList;
129:             EmployeeRepeater.DataBind( );
130:
131:
132:         }
133:
134:         protected void OnNext_Click( object sender, EventArgs e )
135:         {
136:              //save current index
137:              int nLast =  m_ViewerState.m_CurrentIndex;
138:              m_ViewerState.m_IdxStack.Push( nLast);
139:              m_ViewerState.m_CurrentIndex = CalcNextIndex( );
140:              DisplayData( nLast, m_ViewerState.m_CurrentIndex );
141:              UpdateNavigationButtons( );
142:
143:          }
144:
145:          protected void OnPrev_Click( object sender, EventArgs e )
146:          {
147:               int nStop  = (int)m_ViewerState.m_IdxStack.Pop( );
148:               int nStart = (int)m_ViewerState.m_IdxStack.Peek( );
149:               DisplayData( nStart, nStop );
150:               m_ViewerState.m_CurrentIndex = nStop;
151:               UpdateNavigationButtons( );
152:          }
153:
154:          protected int CalcNextIndex( )
155:          {
156:              return (m_ViewerState.m_CurrentIndex + m_ViewerState.m_MaxPerPage) >
 m_ViewerState.m_RowCount
157:                     ? m_ViewerState.m_RowCount : (m_ViewerState.m_CurrentIndex +
 m_ViewerState.m_MaxPerPage);
158:
159:          }
160:
161:          protected void UpdateNavigationButtons( )
162:          {
163:              this.btnNext.Visible = m_ViewerState.m_CurrentIndex < m_ViewerState
.m_RowCount;
164:              this.btnPrev.Visible = (int)m_ViewerState.m_IdxStack.Peek( ) != 0;
165:          }
166:
167:
168:
169:          #region Web Form Designer generated code
170:          /// <summary>
171:          /// Required method for Designer support - do not modify
172:          /// the contents of this method with the code editor.
173:          /// </summary>
174:          private void InitializeComponent()
175:          {
176:              this.Load += new System.EventHandler(this.Page_Load);
177:          }
178:          #endregion
179:     }
180: }

To see how data binding is set up, look at the DisplayData method on line 115. An ArrayList is constructed and Employee objects are added based on the StartIndex and StopIndex arguments to the method. After the ArrayList has been filled as specified, the EmployeeRepeater control is bound to the ArrayList. These bindings are evaluated using the <%# DataBinder.Eval( Container.DataItem, X) %> embedded binding statements.

To maintain view state information, a small ViewerState class is created. The ViewerState maintains a DataSet corresponding to the parameters passed into the page. The ViewerState also maintains the current index and a stack object that holds the previous indexes. This stack is used to facilitate paging to previous pages. The remainder of the code for EmployeeListing consists of data loading, index calculation, and the onclick handlers for the bntNext and btnPrev WebControl buttons.

The Search Page: Where It All Begins

With the internals of the EmployeeBrowser Web application in place, an entry point into the application is needed. A simple search page will fit the bill and allow the user to select the department, first/last name, and the number of listings per page. These choices will then be passed as parameters to the EmployeeListing aspx page for processing.

The Search page shown in Figure 4.3.7 will be used to kick off the EmployeeBrowser Web application.

Figure 4.3.7. Search page.


This is the smallest of all the examples shown so far. Basically, all that is needed is to allow the user to select a department, a first/last name, and the number of listings per page. Again, rather than creating a UserControl-derived pagelet, a small aspx page will be used to gather the input and create the request URL for the EmployeeListing page. Listing 4.3.10 contains the HTML source for the EmployeeSearch.aspx page.

Listing 4.3.10. EmployeeSearch.aspx
 1: <%@ Register TagPrefix="EmployeeBrowser" TagName="HeaderControl" Src="~/Pagelets
/HeaderPagelet.ascx" %>
 2: <%@ Page language="c#" Codebehind="EmployeeSearch.aspx.cs" AutoEventWireup="false"
 Inherits="EmployeeBrowser.EmployeeSearch" %>
 3: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
 4: <HTML>
 5:     <HEAD>
 6:         <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
 7:         <meta name="CODE_LANGUAGE" Content="C#">
 8:         <meta name="vs_defaultClientScript" content="JavaScript (ECMAScript)">
 9:         <meta name="vs_targetSchema" content="http://schemas.microsoft.com
/intellisense/ie5">
10:     </HEAD>
11:     <body MS_POSITIONING="GridLayout">
12:         <form id="EmployeeSearch" method="post" runat="server">
13:
14:     <!--
15:            Insert the custom header control
16:         -->
17:         <EmployeeBrowser:HeaderControl runat="server" Text="Employee Search"
 ImageUrl="~/images/logo.jpg" ID="Headercontrol1" NAME="Headercontrol1" />
18:
19:     <!--
20:            Begin the Search Page Layout
21:         -->
22:         <table style="BORDER-TOP-STYLE: outset; BORDER-RIGHT-STYLE: outset;
 BORDER-LEFT-STYLE: outset; BACKGROUND-COLOR: lightgrey; BORDER-BOTTOM-STYLE: outset">
23:           <tbody>
24:            <tr>
25:             <td>Department</td>
26:             <td>
27:              <asp:dropdownlist id="Departments" runat="server" />
28:             </td>
29:            </tr>
30:
31:            <tr>
32:             <td>First Name</td>
33:             <td>
34:              <asp:textbox runat="server" id="FirstName" />
35:             </td>
36:            </tr>
37:
38:            <tr>
39:             <td>Last Name</td>
40:             <td>
41:              <asp:textbox runat="server" id="LastName" />
42:             </td>
43:            </tr>
44:
45:            <tr>
46:             <td>Max Per Row</td>
47:             <td>
48:              <asp:textbox runat="server" id="MaxPerRow" />
49:             </td>
50:            </tr>
51:
52:            <tr>
53:             <td> <!-- Left Blank to push button to second column --></td>
54:             <td align="right">
55:              <asp:button id="btnGO" onclick="OnSearch_Click" text="GO!" runat="server" />
56:             </td>
57:            </tr>
58:
59:          </tbody>
60:         </table>
61:         </form>
62:     </body>
63: </HTML>

As you can see, the markup is fairly simple. Notice the mixture of standard HTML and ASP.NET. This freedom allows the developer to use the best tool for the job. There is not always a need to require server-side controls, so standard HTML elements fit the bill. The advantage of ASP.NET server-side controls is the ability of the controls to down-level to the client browser.

The code for EmployeeSearch.cs (see Listing 4.3.11) employs many of the techniques of the previous pages developed so far. The Session object is used to hold some mapping information, the asp:dropdownbox makes use of data-binding, and when a PostBack is processed, the element data is retrieved to form the HTTP GET request to the EmployeeListing.aspx page.

Listing 4.3.11. EmployeeSearch.cs
  1: using System;
  2: using System.Collections;
  3: using System.ComponentModel;
  4: using System.Data;
  5: using System.Data.SqlClient;
  6: using System.Drawing;
  7: using System.Web;
  8: using System.Web.SessionState;
  9: using System.Web.UI;
 10: using System.Web.UI.WebControls;
 11: using System.Web.UI.HtmlControls;
 12:
 13: using Stingray.Data;
 14:
 15: namespace EmployeeBrowser
 16: {
 17:     /// <summary>
 18:     /// Summary description for EmployeeSearch.
 19:     /// </summary>
 20:     public class EmployeeSearch : System.Web.UI.Page
 21:     {
 22:         protected System.Web.UI.WebControls.DropDownList Departments;
 23:         protected System.Web.UI.WebControls.TextBox FirstName;
 24:         protected System.Web.UI.WebControls.TextBox LastName;
 25:         protected System.Web.UI.WebControls.TextBox MaxPerRow;
 26:         protected System.Web.UI.WebControls.Button btnGO;
 27:
 28:         protected ArrayList    DepartmentList;
 29:         protected Hashtable    htDeptMapping;
 30:
 31:
 32:         public EmployeeSearch()
 33:         {
 34:            Page.Init += new System.EventHandler(Page_Init);
 35:         }
 36:
 37:         private void Page_Load(object sender, System.EventArgs e)
 38:         {
 39:           if( !this.IsPostBack )
 40:           {
 41:               htDeptMapping = new Hashtable( );
 42:               LoadData( );
 43:
 44:               this.Session.Add( "SEARCH_HT_MAPPING", htDeptMapping );
 45:               Departments.DataSource = DepartmentList;
 46:               Departments.DataBind( );
 47:           }
 48:           else
 49:           {
 50:               htDeptMapping = (Hashtable)this.Session[" SEARCH_HT_MAPPING"];
 51:           }
 52:
 53:         }
 54:
 55:         private void Page_Init(object sender, EventArgs e)
 56:         {
 57:             //
 58:             // CODEGEN: This call is required by the ASP.NET Web Form Designer.
 59:             //
 60:             InitializeComponent();
 61:          }
 62:
 63:          protected void OnSearch_Click( object sender, EventArgs e )
 64:          {
 65:
 66:            //Get the Selected params
 67:            if(this.htDeptMapping == null)
 68:            {
 69:                Response.Redirect( "EmployeeListing.aspx?MaxPerPage=5" );
 70:            }
 71:            else
 72:            {
 73:
 74:                int    DeptId    = (int)this.htDeptMapping[Departments. SelectedItem
.Text];
 75:                string FirstName = this.FirstName.Text;
 76:                string LastName  = this.LastName.Text;
 77:
 78:                int iMaxPerRow    = 5;
 79:
 80:                if( MaxPerRow.Text != "" )
 81:                 {
 82:                    iMaxPerRow = Int32.Parse(this.MaxPerRow.Text);
 83:                 }
 84:
 85:
 86:                 //build the request URL
 87:                 string request;
 88:
 89:                 if( DeptId != 0)
 90:                 {
 91:                   object[] args = {  DeptId, FirstName, LastName, iMaxPerRow } ;
 92:                   request = string.Format("DeptId={ 0} &FirstName={ 1} & LastName={ 2
} &MaxPerPage={ 3} ", args);
 93:                 }  else {
 94:                   object[] args = {  FirstName, LastName, iMaxPerRow } ;
 95:                   request = string.Format("FirstName={ 0} &LastName={ 1}
 &MaxPerPage={ 2} ", args);
 96:                 }
 97:
 98:                 Response.Redirect( string.Format("EmployeeListing.aspx? { 0} ",
 request) );
 99:             }
100:         }
101:
102:         protected void LoadData( )
103:         {
104:
105:              SqlConnection dbCon = DBAccess.AcquireConnection( );
106:              SqlDataAdapter cmd = new SqlDataAdapter( "SELECT * FROM DEPARTMENT",
 dbCon );
107:              DataSet dsResult = new DataSet( );
108:              cmd.Fill( dsResult, "DEPARTMENT" );
109:
110:              DepartmentList = new ArrayList( );
111:              DepartmentList.Add( "All Departments" );
112:              htDeptMapping.Add( "All Departments", 0 );
113:
114:              foreach( DataRow row in dsResult.Tables["DEPARTMENT"].Rows )
115:              {
116:                  Department d = new Department( );
117:                  d.FromDataRow( row );
118:                  DepartmentList.Add( d.Name );
119:                  htDeptMapping.Add( d.Name, d.Id );
120:              }
121:
122:              dbCon.Close( );
123:              dbCon.Dispose( );
124:              dsResult.Dispose( );
125:         }
126:
127:
128:         #region Web Form Designer generated code
129:          /// <summary>
130:          /// Required method for Designer support - do not modify
131:          /// the contents of this method with the code editor.
132:          /// </summary>
133:          private void InitializeComponent()
134:         {
135:              this.Load += new System.EventHandler(this.Page_Load);
136:
137:           }
138:           #endregion
139:     }
140: }

With the completion of the EmployeeSearch page, the EmployeeBrowser application is ready. Of course, some layout and design work would go a long way towards improving the overall appearance of the page but, because the focus is on the code, I'll leave the rest to you.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.94.213