Chapter 11: Creating an XML.NET Guestbook – ASP.Net Web Developer's Guide

Chapter 11

Creating an XML.NET Guestbook

Introduction

Your first case study is a simple online guestbook application, completely coded in ASP.NET. You are going to need to provide the basic functions through this guestbook, namely the ability to do the following:

1. Enable guests to enter messages.

2. Display all messages on one page.

3. Show author, e-mail address of author, and comment from the author of the message.

The flowchart in Figure 11.1 shows the user interaction process that you want to achieve.

Figure 11.1 Basic Functionality Layout

In essence, the user will come to the site and decide if he or she wants to view previous messages or add new messages. The user will be redirected to the view comments page after filling out a new message, or the user viewing the messages has the option to fill out a message.

NOTE

In the CD there are two folders for this chapter, representing two ways of going about this guestbook: one is labeled “basic” and the other is labeled “advanced.” We are going to explore both of these.

All of these functions need to be kept as compact as possible. Our backend needs to store the following information for every message that is left on the guestbook:

 Name

 E-mail

 Subject Line

 Actual Comment

The Name, E-mail, Subject Line, and Actual Comment need to be required fields and you need to provide validation for the e-mail field. Also, you need to provide the user with an easy-to-use interface. A basic interface would consist of the user being able to do the following:

1. Choose between adding a new entry and viewing previous entries.

2. Properly locate the corresponding text areas for the entry points.

3. Have real-time validation take place where needed.

4. Reply to a comment left by a user via e-mail.

Functional Design Requirements of the XML Guestbook

Several guestbooks are already available online for download, but most require either a Microsoft Access database or an SQL Server database for storing the guestbook entries and other information pertinent to that guestbook. While both of these tools provide their own strengths and weaknesses, you want to provide an application that is small, quick, and able to stand alone without requiring a separate application to make it work. This type of thought also implies that the application will be small and easy to transfer, if needed. You also need to keep an eye on the code and keep it as small as possible. You need to be able to write directly to the database and read from the database with as little code as possible. Just because you are trying to make the code portable doesn’t mean you need to make the code bloat!

So, if you are not going to use a traditional database (such as Microsoft Access or SQL Server), then what can you use that won’t kill the application requirements? Back in Chapter 8 we talked about a technology that is turning into a strong database alternative, called XML. XML will enable you to use a text-based approach to your database that does not rely on any ODBC connections or even any server (although your code will pretty much lock you into a server that uses ASP.NET). Also, through an XML schema you can define how our XML “row” will look and what each value must contain.

With your backend solution set at XML you need to determine how you are going to work with the XML file. The logical choice is the System.XML namespace, but you can actually find a faster method by using the XML tools that accompany the System.Data namespace. Even though System.XML is more powerful than System.Data when it comes to XML, you simply don’t need to rely on so much coding to see your results.

NOTE

The choice of System.Data over System.XML does not mean that System.XML is in any way inefficient. It simply means that, as programmers, we sometimes have to choose between a solution that requires more time but is more flexible, and a solution that is quicker but more rigid. System.XML is more flexible with XML than System.Data will ever be, but all you need for this case study is just to be able to read and write to an XML file. In other words, you are following an age-old adage of programming—K.I.S.—”Keep It Simple!”

Constructing the XML

Even though System.Data is viewed more or less as a method of working with traditional database connections, such as a SQL database or an Access database, it can also work with XML data, provided the XML has an inline schema that it can match the data against; almost like looking at the table structure first and then the data within it.

The file gbook.xml (shown in Figure 11.2, and in the Basic directory on the CD that accompanies this book) displays the XML code that we will be working with.

Figure 11.2 gbook.xml (Basic Version)

Lines 1 and 26 have the root tags for the XML file. In this example, we are using “gbook” but you can use anything. Lines 2 through 6 are one line that we used whitespace to organize the attributes in order for the tag to be more readable. The targetNamespace and xmlns attributes in the <xsd:schema> tag are left blank since both the targetNamespace and xmlns are inline. The xsd attribute is pointing to the current schema, and the special Microsoft attribute msdata points to a Microsoft data compatibility namespace.

NOTE

If you want more information on the XSD and MSDATA attributes, you can find documentation for XML schemas online through http://msdn.microsoft.com/library and www.w3.org/XML/Schema.html.

Lines 8 through 24 construct the element that will store the data. When the data is entered into the corresponding .aspx file, it will format the data within the XML per the data outline within the schema. In this case, a sample entry in our guestbook will appear as the following:

This information will be created by your application through the System.Data namespace. In order to be able to do it, System.Data matches the information input to the inline schema and creates the appropriate record. Now that you have set up the “template,” you can get started with the code that adds records. Refer to Figure 11.3 for the logic behind the XML file.

Figure 11.3 Creating a Record Using the XML Schema

Adding Records to the Guestbook

Any veteran ASP developers are going to notice in this section a distinct change. Remember in desktop applications that you formed your GUIs using a Form? Well, in ASP.NET, the Form has been brought to Web development and is referred to as a Panel. You are going to work with your code inline for just this chapter so that you can get a good grasp of what a Panel looks like and how it works within ASP.NET.

There are no real differences between using a Form for desktop applications and a Panel for online applications. Many of the same subs are intact, such as OnLoad, and Panel can reference any item within the Panel, just like in desktops. A great place to view the Panel in ASP.NET is within the UI for adding guestbook records. Your file will be called add.aspx, and is the code is displayed in Figure 11.4 (note that some lines wrap), and in the Basic directory on the CD that accompanies this book.

Figure 11.4 Sample ASPX Code add.aspx (Basic Version)

It may look daunting at first, but it really is quite simple. Remember that in ASP.NET you first should declare the language the page is going to be using. While it is redundant, since the language declaration on the <script> tag determines the actual language use, it is still a good coding practice to get into. Lines 2 through 4 declare the namespaces that you are going to use—System, System.IO, and System.Data. Lines 5 through 8 just display the HTML code that needs to be in every single HTML page.

You then hit the script tag that controls the Submit button event (lines 9 through 10). For now it’s just a placeholder for the code you’ll be adding in later. Notice that the code is placed at the head of the html file, which means that it will be processed before anything else. You’ll look at the Submit button event after you dissect this portion of the ASP.NET page.

Understanding the pnlAdd Panel

On line 19 of Figure 11.4, pnlAdd is declared; it is the name of the panel that contains the programming code displaying the messages and text boxes that the user will be viewing on the page, in order to enter the guestbook entry data; e.g., the name area, the name entry textbox, the e-mail area, the e-mail entry textbox, the comment area, the comment entry textbox, and the Submit button. In other words, it is your run-of-the-mill HTML form but with ASPX. In reality there are only two “normal” form objects; the name textbox is your standard text object, and the comment area is your standard multilane textbox.

The e-mail area, however, is another story. Take a look at the behemoth of a line that you’ll find in line 32:

Starting from the top, you find your standard ASPcontrol declaration as a textbox with its default text set to empty and an ID of “E-mail.” Right after it comes the ASP control declaration for RequiredFieldValidator set to validate the control labeled “E-mail” and with a static display. You then implement two types of validation to the field. The first validation is through the RegularFieldValidator control:

<asp:RequiredFieldValidator ControlToValidate=Email display=static runat=server>This is required.</asp:RequiredFieldValidator>

All you are doing here is a quick check to see if the field is empty or not. If the user skips the field and leaves it empty, then a little message in red shows up saying that “This is required.” You don’t have to use that text but it works for this example. Our second round of validation begins right after that line with the more intense RegularExpressionValidator object:

Developing & Deploying …

Stricter E-Mail Validation

The method of e-mail validation demonstrated in this chapter is not the only option available to you. There is a stricter method for e-mail validation that would only enable the user to input a .com, .org, .edu, .mil, .gov, or .net:

ValidationExpression = “^[\w–]+@[\w–]+\.(com|net|org|edu|mil|gov)$”

You first set the object to bind itself to the E-mail control. It will be analyzing the contents within the E-mail object to see if it falls under the Validation Expression that it has been given; in this case, it checks to see that an “@” symbol as well as a “.” is present within the string. You may want to read up on RegEx to fully understand what variables can be used with Regular Expressions.

Adding a Thank-You Panel with PnlThank

All you are doing here is declaring a panel that will show up after a successful guestbook entry has been added to the XML file. The link in order to view the guestbook is declared and set. Very simple and very quick, to the point, starting on line 48 (Figure 11.4):

Exploring the Submit Button Handler Code

Now that you have established your design and layout, you can take a look at the code that actually handles the addition of new entries into the guestbook. The basic functionality of this code is to react to the Submit button when pressed, and write the necessary items to the XML file. Figure 11.5 walks you through an overview of the Submit button code.

Figure 11.5 Submit Button Handler Code for add.aspx (Basic Version)

Line 1 starts you off with your VB code, declaring itself a code segment that is run on the server-side and written using VB. Line 1 uses an ASP.NET form subnamed “AddClick”; this code segment will be providing all of the functionality of the Submit button.

On line 3, you start taking advantage of one of VB’s newest and very useful feature, error trapping. Your try/catch segment starts out by declaring a variable to store the location of your XML file, which can be any directory. You can just assume that for this example it’s in the gb directory on the root folder of the site. With the location of the file stored, you can open up a FileStream object to open and process the XML file for you. FileStream needs to know the actual location of the file (not the virtual location) of the file, so you use Server.MapPath() to return the actual location of the file to your FileStream object, which you can then open (FileMode.Open) and start reading (FileAccess.Read). You can also tell FileStream how to handle other events, such as sharing; by telling FileStream to allow read/write sharing of the file (FileShare.ReadWrite), you don’t have to worry about your XML file suffering from any file locking, which would prevent any other user from editing the file and getting them a nasty error.

Migrating…

Online Forms

As you have noticed and learned throughout this book, ASP.NET enables programmers to use Web forms, which can be described as the VB6.0 desktop form. In this particular example, your “AddClick” sub would be placed within the OnClick() event for whatever button you wanted to use as your trigger for this action. One other little trick is to view each “panel” as a small form within an mdi, namely the browser window, with their own “hide” and “show” features.

With your XML file stored within the fout object (line 10 in Figure 10.5) you can start to create the object that will handle parsing the data, DataType, and properly formatting it and writing to the XML file, DataRow. Specifically, DataType will handle reading the information and transforming it to a table format. DataRow will then use the information stored within your DataType object to create a new row with the columns that it finds within the DataType object. In other words, when DataType reads your XML file, it will see the root element “gbook” as your table, “gbooky” as your rows, and all the information within “gbooky” as columns. It will write the information out accordingly to the XML file. It will know what it’s writing since it’s using the inline schema (Figure 10.2) to write to the file per the schema, using the WriteXML class of the DataType object and having it write the stream matching the XMLSchema (XMLWriteMode. WriteSchema). You then hide the panel that contains the text boxes and Submit button, and make the panel that contains the “Thank You” message. Figures 10.6 and 10.7 show the basic add.aspx file before and after filling out a new entry.

Figure 11.6 Before Adding a New Entry

Figure 11.7 After Adding a New Entry

Developing & Deploying …

File Locking

File Locking is a basic response to multiple users trying to read and modify the same file at around the same time. I say at “around” the same time because File Locking will take place if the file is accessed at the same time, or if access is attempted after someone already has access to it. By preventing multiple users from reading and writing the file, you avoid file corruption and constant backup restorations. File Locking allows a temporary “lock” to be placed to the file that allows for changes to be made one after the other without damaging the integrity of the file.

Viewing the Guestbook

One line of actual ASPX code—that’s about as simple as it gets, and done just by using the built-in XML server control. You may remember in Chapter 3 that ASP.NET has several controls built in to facilitate many different HTML functions, such as displaying radio buttons and handling forms, which allows ASP.NET to generate items fairly on-the-fly. XML is no exception to this rule.

Displaying Messages

Here is our one-line masterpiece, as shown in Figure 11.8. In essence, all we did to get the sample output shown in Figure 11.8 was just to tell the ASP.NET XML control to read the data in gbook.xml, and to transform it according to the XSL information in gbook.xsl. It is displayed in Figure 11.9 and can be found in the gb folder in the Basic directory on the CD that accompanies this book. Figure 11.10 shows us the output.

Figure 11.8 viewplain.aspx (Basic Directory)

Figure 11.9 gbook.xsl

Figure 11.10 Viewing Basic Guestbook Entries

NOTE

If you have no other recourse but to use XSL to also generate your hyperlinks, the fastest work around to this is will be to simply add the <a> element with an attribute of href and nesting the e-mail element.

Advanced Options for the Guestbook Interface

Now that you have a good understanding of a guestbook and how it works, you can try to do something you haven’t done yet—actually make it look cool! Just

because you are working with ASP.NET does not mean that you cannot use its new tricks to come up with some really jazzy items and tweak your XML a bit. Let’s start by looking at your guestbook entry page.

Manipulating Colors and Images

Clearly this is a design point and not a very strong showing of ASP.NET. However, how you design your page is just as vital as how you design a graphical user interface. In this example, I made the design pleasing to the eye, and I try to use a couple of design techniques to lure the user’s eye to the proper areas on the add screen. While these are basic points, it’s a good idea to keep the following in mind:

1. Is the area visible on most monitors? (Start off at 800×600 resolution.)

2. Will the user be able to understand what to do?

3. If the user cannot easily figure out what to do, should an easy-to-find help link be visible, or should you perhaps change the design?

One of the nice things about ASP.NET controls is that you can still use tags with them. In fact, this second version of my add entry page looks so nice because I’m using a Cascading Style Sheet (CSS) script with it (in the CD that accompanies this book as gbook.css in the Advanced directory). Another part of this new design that you haven’t seen before are the emoticons. Emoticons add a little bit of interactivity to the guestbook by enabling users to pick an image that reflects their “feelings” at the time of posting. You will have to add a couple of changes to the XML file and to the add.aspx file as well as to the view.aspx file in order to display the images. Figure 11.11 will show you how the new add.aspx page will look before and Figure 11.12 after entering a message.

Figure 11.11 add.aspx Before Entering a Comment (Advanced Version)

Figure 11.12 add.aspx After Entering a Comment (Advanced Version)

Line 16 in Figure 11.13 reflects the change from the previous XML code; all that happened was just to create a new element of “img” to under complex type “gbook.” Your code will read this value and assign the correct image for it. For right now all you are doing is just preparing the inline schema to support the value so that when you store the data it will know where to put it.

Figure 11.13 gbook.xml (Advanced Version)

Now for your code; first, you have to add the new row to your Submit button handler at the top in order to include the new Emoticon element within the XML (Figure 11.14).

Figure 11.14 Your Changed add.aspx Submit Handler Code (Advanced Version)

The final change to your add entry is an option button for the image selection; you can add this code anywhere in the add.aspx within the display area. We set ours right after the name.

Modifying the Page Output

You don’t really want to display the same boring, old structured output, so try using some tables to break things up a bit. You are going to take a look at this code a bit differently by starting with the page load code (Figure 11.15).

Figure 11.15 view.aspx (Advanced Version)

You are telling the server that when the page loads (before ANYTHING else is processed, including HTML) create a dataset (ds) and a filestream (fs) to the XML file. Then you tell the dataset (ds) to read the XML file and bind the information to the “gbook” object with the information contained in the dataset. You close the filestream and finish your initialization code. Your display code has undergone some major changes as well (see Figure 11.16, note that some lines wrap).

Figure 11.16 Your Changed Display Code add.aspx (Advanced Version)

NOTE

This code has had all of the graphical changes stripped; if you want to see the code as the screenshots display it, please check the code on the accompanying CD.

Instead of using the asp:xml server control, you are using the Repeater control and a DataSource. Lines 2 and3 have the two namespaces that you are going to need for your script tag. System.IO handles the Filestream object and System.Data handles the DataSource object. The information acquired from the Page_Load sub will generate the information that is bound to the Repeater object. The Repeater object (id=“gbook”) will read the information bound to it, write the header, and then repeat the sequence within the item template until it finishes; then the footer will be written and the asp:repeater object will close. Line 17 shows your only change to the Repeater by adding the link to the image stored by the image tag. The code above plus the graphical add-ons gives you the happy result as seen in Figure 11.17.

Figure 11.17 view.aspx + graphics (Advanced Version)

Summary

Well, we started off with basically nothing and finished up with something that is not only useful but can be pleasing to the eye as well. Hopefully this chapter has introduced some concepts that are useful, not only to your hobby programming but also in your work.

XML and ASP.NET can work well together in a variety of ways: from simple reading and writing to proper design and look. Using a combination of either the System.Data namespace and the ASP server objects, you can create a single-line parsing .aspx page or a more robust page with tables, rows, columns, and different colors and graphics. In order to achieve the best performance available, the System.Data namespace requires an inline schema within the XML file, which the System.Data namespace can reference against when reading or writing XML.

ASP server objects themselves are very flexible in that they can be stand-alone and provide an area to insert inline ASPX code. In the Advanced guestbook, you made heavy use of the inline functions, wrapping table rows and columns around them to provide a view that was readable. Also, by using an inline function you were able to receive the correct image file associated for an emoticon, by placing it within the image html tag. Combined with Cascading Style Sheets (CSS), this method proved capable and provided ample room to grow with.

Solutions Fast Track

Functional Design Requirements of the XML.NET Guestbook

 XML enables you to use an interface that is both universally read and universally accessed. You do not have to use bulky components such as SQL or Access databases for simple—and even some complicated—database solutions.

 XML provides a schema to use with XML in order to provide validation for data.

Adding Records to the Guestbook

 When working with the System.Data namespace and planning to write XML, you need to make sure that you have a properly validated inline XML schema, or else the code will not work.

 Even though you can use the XML schema to help determine certain validation points, it is better to have the ASP.NET provide the validation of certain entries, such as e-mail, due to the powerful use of Regular Expressions.

Viewing the Guestbook

 Using System.Data can provide a fast, efficient forward-only read and write solution that is perfect for reading and writing to XML files that are not dependant on heavy node interaction, and that just need information added to them.

 Cascading Style Sheets provide a way to create a more pleasing guestbook without having to change any code structure.

Advanced Options for the Guestbook Interface

 The ASP.NET controls are very versatile and efficient. Keep in mind that by combining them with Cascading Style Sheets, their obvious lack of visual aids are easily bypassed for a true eye-candy feel.

 The asp:repeater object needs to have a <headertemplate>, an <itemtemplate>, and a <footertemplate> within it to function.

 The only part of the asp:repeater object that actually repeats is the <itemtemplate> section.

Frequently Asked Questions

The following Frequently Asked Questions, answered by the authors of this book, are designed to both measure your understanding of the concepts presented in this chapter and to assist you with real-life implementation of these concepts. To have your questions about this chapter answered by the author, browse to www.syngress.com/solutions and click on the “Ask the Author” form.

Q: Why does the add.aspx code need the inline XML schema?

A: Add.aspx uses the schema to retrieve the way it needs to write the data to the XML file in the proper order. Say that instead of name before e-mail, you had e-mail before name; add.aspx would write the row with the e-mail field first instead of the name field.

Q: Why won’t the simple guestbook show?

A: .NET expects www.w3.org/1999/XSL/Transform as the XSLT namespace. This does limit you a bit, since the Working Draft version is extremely better than the 1999 version.

Q: I get an error that says, “compilation error, (addClick or Page_Load) is not part of asp:(add.aspx or viewbook.aspx)”. What does that mean?

A: Unfortunately, some of the error handling for ASP.NET still needs tweaking; this is a perfect example. When running the aspx page, it will spit out errors when it finds them within the asp objects, but is not very good at reporting errors within the subs located within the <head> tag. When you see these errors, check the code and try again.