2. When the app executes, another compiler (known as the just-in-time compiler
23.8 Case Study: Database-Driven ASP.NET Guestbook
guage in theOptions.aspxpage, theHttpSessionStateobject’sCountproperty will be0 (line 11). This property provides the number of session items contained in aHttpSes-
sionStateobject. If theCountis0, then we display the textNo Recommendations(line 22), hide the ListBox (line 23) and update the Text of the HyperLink back to Op-
tions.aspx(line 26).
If the user chose at least one language, the loop in lines 14–16 iterates through the
HttpSessionState object’s keys (line 14) by accessing the HttpSessionState’s Keys property, which returns a collection containing all the keys in the session. Lines 15–16 concatenate thekeyName, the String " How to Program. ISBN#: "and the key’s corre- sponding value, which is returned bySession[keyName]. ThisStringis the recommen- dation that’s added to theListBox.
23.8 Case Study: Database-Driven ASP.NET Guestbook
Many websites allow users to provide feedback about the website in a guestbook. Typical- ly, users click a link on the website’s home page to request the guestbook page. This page usually consists of a form that contains fields for the user’s name, e-mail address, message/
1 // Fig. 23.30: Recommendations.aspx.cs
2 // Creates book recommendations based on a Session object.
3 using System;
4
5 public partial class Recommendations : System.Web.UI.Page 6 {
7 // read Session items and populate ListBox with recommendations 8 protected void Page_Init( object sender, EventArgs e )
9 {
10 // determine whether Session contains any information
11 if ( != 0 )
12 {
13 14 15 16
17 } // end if
18 else
19 {
20 // if there are no session items, no language was chosen, so 21 // display appropriate message and clear and hide booksListBox 22 recommendationsLabel.Text = "No Recommendations";
23 booksListBox.Visible = false; 24
25 // modify languageLink because no language was selected 26 languageLink.Text = "Click here to choose a language";
27 } // end else
28 } // end method Page_Init 29 } // end class Recommendations
Fig. 23.30 | Session data used to provide book recommendations to the user.
Session.Count
// display Session's name-value pairs foreach ( string keyName in Session.Keys )
booksListBox.Items.Add( keyName +
" How to Program. ISBN#: " + Session[ keyName ] );
feedback and so on. Data submitted on the guestbook form is then stored in a database located on the server.
In this section, we create a guestbook Web Form app. The GUI (Fig. 23.31) contains aGridViewdata control, which displays all the entries in the guestbook in tabular format.
This control is located in theToolbox’sDatasection. We explain how to create and con- figure this data control shortly. TheGridViewdisplaysabcinDesignmode to indicate data that will be retrieved from a data source at runtime. You’ll learn how to create and con- figure theGridViewshortly.
The Guestbook Database
The app stores the guestbook information in a SQL Server database calledGuestbook.mdf
located on the web server. (We provide this database in thedatabasesfolder with this chapter’s examples.) The database contains a single table namedMessages.
Testing the App To test this app:
1. SelectOpen Web Site…from theFILEmenu.
2. In theOpen Web Sitedialog, ensure thatFile Systemis selected, then navigate to this chapter’s examples, select theGuestbookfolder and click theOpenButton. 3. SelectGuestbook.aspxin theSolution Explorer, then typeCtrl+F5to execute
the web app in your default web browser.
Figure 23.32(a) shows the user submitting a new entry. Figure 23.32(b) shows the new entry as the last row in theGridView.
Fig. 23.31 | Guestbook app GUI inDesignmode.
GridView control
23.8 Case Study: Database-Driven ASP.NET Guestbook 935
23.8.1 Building a Web Form that Displays Data from a Database
You’ll now build this GUI and set up the data binding between theGridViewcontrol and the database. Many of these steps are similar to those performed in Chapter 22 to access and interact with a database in a Windows app. We discuss thecode-behind filein Section 23.8.2.
Step 1: Creating the Web Site
To begin, follow the steps in Section 23.4.1 to create anEmpty Web SitenamedGuestbook then add a Web Form namedGuestbook.aspxto the project. Set the document’sTitle property to"Guestbook". To ensure thatGuestbook.aspxloads when you execute this app, right click it in theSolution Explorerand selectSet As Start Page.
Fig. 23.32 | Sample execution of theGuestbookapp.
a) User enters data for the name, e-mail and message, then pressesSubmit to send the data to the server
b) Server stores the data in the database, then refreshes the GridViewwith the updated data
Step 2: Creating the Form for User Input
InDesignmode, add the textPlease leave a message in our guestbook:, then use the
Block FormatComboBoxin the IDE’s toolbar to change the text toHeading 3format. Insert a table with four rows and two columns. Place the appropriate text (see Fig. 23.31) in the top three cells in the table’s left column. Then place TextBoxes named nameTextBox,
emailTextBoxandmessageTextBoxin the top three table cells in the right column. Con- figure theTextBoxes as follows:
• SelectFORMAT > New Style…to display theNew Styledialog. In theSelectorfield, specify.textBoxWidthas the new style’s name. Select theCategorynamedPosi-
tion, then set thewidth:to300pxand clickOKto create the style and dismiss the dialog. Next set theCssClassproperty for both thenameTextBoxandemailText- BoxtotextBoxWidth. This uses the style to set bothTextBoxes to300pixels wide.
• SelectFORMAT > New Style… to display theNew Style dialog. In the Selector field, specify.textBoxHeightas the new style’s name. Select theCategorynamed
Position, then set theheight:to100pxand clickOKto create the style and dismiss the dialog. Next setmessageTextBox’sCssClassproperty to
This uses both the.textBoxWidthand.textBoxHeightstyles to set message-
TextBox’s width to300pixels and height to100pixels. Also setmessageTextBox’s
TextModeproperty toMultiLineso the user can type a message containing mul- tiple lines of text.
Finally, addButtons namedsubmitButtonandclearButtonto the bottom-right table cell. Set the buttons’Textproperties toSubmitandClear, respectively. We discuss the buttons’ event handlers when we present the code-behind file. You can create these event handlers now by double clicking eachButtoninDesignview.
Step 3: Adding aGridViewControl to the Web Form
Add aGridViewnamedmessagesGridView that will display the guestbook entries. This control is located in theToolbox’sDatasection. The colors for theGridVieware specified through theAuto Format...link in theGridView Taskssmart-tag menuthat opens when you place theGridViewon the page. Clicking this link displays anAutoFormatdialog with sev- eral choices. In this example, we choseProfessional. We show how to set theGridView’s data source (that is, where it gets the data to display in its rows and columns) shortly.
Step 4: Creating the Entity Data Model
Next, you’ll add an entity data model to the project. Perform the following steps:
1. Right click the project name in the Solution Explorer and selectAdd > Add New Item…to display theAdd New Itemdialog.
2. SelectADO.NET Entity Data Model, change the Nameto GuestbookModel.edmx
and clickAdd. A dialog appears asking if you would like to put your new entity data model classes in theApp_Code folder; click Yes. The IDE will create an
App_Codefolder and place the entity data model classes information in that fold- er. For security reasons, this folder can be accessed only by the web app on the server—clients cannot access this folder over a network.
textBoxWidth textBoxHeight
23.8 Case Study: Database-Driven ASP.NET Guestbook 937
3. Next, theEntity Data Model Wizard dialog appears. Ensure thatGenerate from databaseis selected so that you can generate the model from theGuestbook.mdf
database, then clickNext >.
4. In the Entity Data Model Wizarddialog’sChoose Your Data Connectionstep, click
New Connection…then use theConnection Propertiesdialog to locate theGuest-
book.mdfdatabase file (included in thedatabasesfolder with this chapter’s ex- amples). ClickOK to create the connection, then clickNext >to complete the
Choose Your Data Connectionstep.
5. A dialog appears asking if you would like to copy the database file into your proj- ect. ClickYes. The IDE will create anApp_Data folder and place theGuest- book.mdffile in that folder. Like theApp_Codefolder, this folder can be accessed only by the web app on the server.
6. In theEntity Data Model Wizarddialog’sChoose Your Database Objects and Set- tingsstep, select theMessagestable from the database. By default, the IDE names the modelGuestbookModel. Ensure thatPluralize or singularize generated object namesis checked, keep the other default settings and clickFinish. The IDE dis- plays theGuestbookModelin the editor, where you can see that aMessagehas a
MessageID, Date,Name,EmailandMessage1property.Message1was renamed fromMessageby the IDE so that it does not conflict with the entity data model’s
Messageclass.
7. SelectBUILD > Build Solutionto ensure that the new entity data model classes are compiled.
Step 5: Binding theGridViewto theMessagesTable of theGuestbookDatabase You can now configure theGridViewto display the database’s data.
1. In theGridView Taskssmart-tag menu, select<New data source...>from theChoose
Data SourceComboBoxto display theData Source Configuration Wizarddialog.
2. In this example, we use aEntityDataSourcecontrol that allows the app to inter- act with theGuestbook.mdfdatabase. SelectEntity, then in theSpecify an ID for the data sourcefield entermessagesEntityDataSourceand clickOKto begin the
Configure Data Sourcewizard.
3. In theConfigure ObjectContext step, select GuestbookEntities in the Named
ConnectionComboBox, then clickNext >.
4. TheConfigure Data Selectionscreen (Fig. 23.33) allows you to specify which data theEntityDataSourceshould retrieve from the data context. TheEntitySetName
drop-down list containsDbContextproperties that represent database’s tables. For theGuestbookdatabase, selectMessagesfrom the drop-down list. In theChoose
the properties in the query result:pane, ensure that theSelect Allcheckbox is selected to indicate that you want to retrieve all the columns in theMessagestable.
5. ClickFinish to complete the wizard. A control named messagesEntityData- Sourcenow appears on the Web Form directly below theGridView. It’s repre- sented inDesignmode as a gray box containing its type and name. It willnot appear on the web page—the gray box simply provides a way to manipulate the
control visually throughDesignmode—similar to how the objects in the compo- nent tray are used inDesignmode for a WindowsForms app.
6. Click the messagesEntityDataSource, then select Refresh Schema from its smart-tag menu. TheGridViewupdates to display column headers that corre- spond to the columns in theMessagestable (Fig. 23.34). The rows each contain either a number (which signifies anautoincremented column) orabc(which indi- cates string data). The actual data from theGuestbook.mdfdatabase file will ap- pear in these rows when you view the ASPX file in a web browser.
Step 6: Customizing the Columns of the Data Source Displayed in theGridView It’s not necessary for site visitors to see theMessageIDcolumn when viewing past guest- book entries—this column is merely a unique primary key required by theMessagestable within the database. So, let’s modify theGridViewto prevent this column from displaying on the Web Form. We’ll also modify the columnMessage1to readMessage.
1. In theGridView Taskssmart tag menu, clickEdit Columnsto display theFieldsdi- alog (Fig. 23.35).
2. SelectMessageIDin theSelected fieldspane, then click the Button. This re- moves theMessageIDcolumn from theGridView.
Fig. 23.33 | Configuring theEntityDataSource.
23.8 Case Study: Database-Driven ASP.NET Guestbook 939
Fig. 23.34 | Designmode displayingEntityDataSourcecontrol for aGridView.
Fig. 23.35 | Removing theMessageIDcolumn from theGridView.
EntityDataSource control
3. SelectMessage1in theSelected fieldspane and change itsHeaderTextproperty toMessage. The IDE renamed this field to prevent a naming conflict in the entity data model classes. ClickOKto return to the main IDE window.
4. Next create a style to specify the width of theGridView. SelectFORMAT > New Style…to display theNew Styledialog. In theSelectorfield, specify.gridView-
Widthas the new style’s name. Select theCategorynamedPosition, then set the
width:to650pxand clickOKto create the style and dismiss the dialog. Next set theCssClassproperty for themessagesGridViewtogridViewWidth.
TheGridViewshould now appear as shown in Fig. 23.31.
23.8.2 Modifying the Code-Behind File for the Guestbook App
After building the Web Form and configuring the data controls used in this example, dou- ble click theSubmitandClearbuttons inDesignview to create their correspondingClick event handlers in the code-behind file (Fig. 23.36). The IDE generates empty event han- dlers, so we must add the appropriate code to make these buttons work properly. The event handler forclearButton(lines 39–44) clears eachTextBoxby setting itsTextprop- erty to an empty string. This resets the form for a new guestbook submission.
1 // Fig. 23.36: Guestbook.aspx.cs
2 // Code-behind file that defines event handlers for the guestbook.
3 using System;
4
5 public partial class Guestbook : System.Web.UI.Page 6 {
7 // Submit Button adds a new guestbook entry to the database,
8 // clears the form and displays the updated list of guestbook entries 9 protected void submitButton_Click( object sender, EventArgs e )
10 {
11 // use GuestbookEntities DbContext to add a new message
12 using ( GuestbookEntities dbcontext = new GuestbookEntities() )
13 {
14 15 16 17 18 19 20 21 22 23 24 25 26
27 } // end using statement 28
Fig. 23.36 | Code-behind file for the guestbook app. (Part 1 of 2.)
// create a new Message to add to the database; Message is // the entity data model class representing a table row Message message = new Message();
// set new Message's properties
message.Date = DateTime.Now.ToShortDateString();
message.Name = nameTextBox.Text;
message.Email = emailTextBox.Text;
message.Message1 = messageTextBox.Text;
// add new Message to GuestbookEntities DbContext dbcontext.Messages.Add( message );
dbcontext.SaveChanges(); // save changes to the database