Common ASP Tasks and Their ASP.NET Equivalents

I l @ ve RuBoard

Common ASP Tasks and Their ASP.NET Equivalents

To help ease your transition from Classic ASP to ASP.NET, let's take a look at some of the more common ASP applications and see how they would be done using ASP.NET. This section examines examples such as how to do a very simple user login screen, how to make a form post back to itself and persist its values, and how to display the contents of a recordset in a table. You will also look at a way to use Classic ASP page template include files in ASP.NET pages by using user controls.

Read a Form

One of the most common tasks performed by an ASP page is reading and working with output from HTML forms, using the Request object. In keeping with the theme of this chapter, we'll take a look at a very simple ASP page that takes form input and outputs it to the screen. We'll also demonstrate how to maintain state of form elements. Then we'll demonstrate how to do the same thing using ASP.NET, both in VB and C#. These simple examples will help prepare us for more advanced scenarios in this chapter and the rest of the book.

First, let's look at the ASP version of a form that collects some very simple information from the user, and when the Save button is clicked, returns a simple message and retains all of their selections in the form. This example makes use of textboxes, checkboxes, and select listboxes, and is shown in Figure 3.2.

Figure 3.2. Our sample HTML form.

For an ASP page to parse this form, it must do several things. First, it needs to determine whether or not the form has been submitted or not, so that it knows whether to display the special message. Second, it must assign the request variables to local variables to ensure optimum performance. Finally, it must use these local variables in displaying the form itself, in order to persist the values selected previously. All of this means that there is ASP code interspersed throughout our final product, as shown in Listing 3.4.

Listing 3.4 Source code for readrequest.asp.
 <%Option Explicit%> <% Dim first_name Dim age Dim married_check Dim married Dim sex Dim strOutput Dim fSubmit first_name  = Request.Form("first_name") age = Request.Form("age") married = Request.Form("married") sex = Request.Form("sex") If married <> "" Then     married_check="checked"     married = "married" Else     married_check = ""     married = "single" End If 'Check postback fSubmit = Request("btnSubmit") = "Save" If fSubmit Then     strOutput = "Hello, " & first_name & ".  You are a " & age & " year old, "  & married & " " & sex & "." End If %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>ASP Forms</title> </head> <body> <form action="<%=Request.Servervariables("URL")%>" method="post" id="form1" name="form1"> <table border="1" bgcolor="#EEEEEE">     <caption>Forms</caption>     <tr>         <td>First Name</td>         <td><input type="text" name="first_name" value="<%=first_name%>"></td>     </tr>     <tr>         <td>Age</td>         <td><input type="text" name="age" value="<%=age%>"></td>     </tr>     <tr>         <td>Married?</td>         <td><input type="checkbox" name="married" <%=married_check%>></td>     </tr>     <tr>         <td>Sex</td>         <td><select name="sex">             <% If sex="male" Then %>                 <option value="female">Female</option>                 <option selected value="male">Male</option>             <% Else %>                 <option selected value="female">Female</option>                 <option value="male">Male</option>             <% End If %>             </select>         </td>     </tr>     <tr>         <td colspan="2" align="center">             <input type="submit" name="btnSubmit" value="Save">         </td>     </tr> </table> </form> <%=strOutput%> </body> </html> 

There are, of course, many different techniques to do what this ASP page is doing. However, ASP is not the topic of this book, so we won't go into detail about other methods of persisting form values or why we chose the methods we did. Suffice to say that the preceding page works as expected.

Thankfully, in ASP.NET, we can separate out the form's presentation code from the programming code of the page. ASP.NET takes care of maintaining the state of the form elements for us as long as we declare our controls using runat ="server" . As you will see, ASP.NET offers two different sets of controls for describing form elements: HTML controls and Web controls. The names are very similar, so it is easy to get these confused . HTML controls look just like standard HTML, but with the attribute of runat="server" added to them. For example, the following is an HTML control:

 <input type="text" id="first_name" runat="server"> 

Web controls also require the use of runat="server" , but are an entirely new syntax from anything available in ASP prior to ASP.NET. These controls use a tagprefix of asp , followed by the name of the control. Tagprefixes provide a way to uniquely identify controls that might otherwise have the same name. In this case, our control name is TextBox, and our complete Web Control tag would look like this:

 <asp:TextBox id="first_name" runat="server" /> 

The actual HTML output by both of these controls is nearly identical. The first outputs this HTML:

 <input name="first_name" id="first_name" type="text" /> 

And the second produces this output:

 <input name="first_name" type="text" id="first_name" /> 

And why, you may ask, are there two different ways to do the same thing? Well, the former method uses code that "looks" more like plain HTML. This makes it a good choice if you are working with a GUI HTML editor or with separate programmers and HTML designers. The second method allows for more programmatic control, and has more of a VB "feel" to its usage. The choice of which to use is largely a matter of taste; for the examples in this chapter we will use Web controls. Chapter 5, "HTML/Web Controls," covers this topic in detail.

You will note that in the ASP.NET version of readrequest.asp, there is no programming code within the HTML section of the page. In fact, a powerful method of coding ASP.NET pages is through the use of a codebehind page, in which all of the programming code is kept in a separate file entirely, completely separating HTML layout and presentation logic from programming code. For clarity, we are presenting these examples as single files, but in later chapters some examples will use the codebehind style. Whether or not you choose to use codebehind pages is largely a question of style.

Neither one performs better than the other. If you are using Visual Studio. NET, however, the default method is to use codebehind files, and some of the features, like code completion, are not available for single-page ASP. NET pages. Listing 3.5 displays readrequestVB.aspx, the VB version of our ASP.NET page.

Listing 3.5 Source code for readrequestVB.aspx.
 <%@ Page Language="VB" Trace="False" %> <script runat="server"> Sub Page_Load(Src As Object, E As EventArgs)     Dim strMarried As String     If Not Page.IsPostBack Then         'Build listbox -- this could be stored in a user control         sex.Items.Add("Female")         sex.Items.Add("Male")     Else         If married.Checked Then             strMarried = "married"         Else             strMarried = "single"         End If         output.Text = "Hello, " & first_name.Text & ".  You are a " & age.Text  & " year old, " & strMarried & " " & sex.SelectedItem.Text & "."     End If End Sub </script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>ASP Forms</title> </head> <body> <form runat="server" id="form1"> <table border="1" bgcolor="#EEEEEE">     <caption>Forms</caption>     <tr>         <td>First Name</td>         <td><asp:Textbox runat="server" id="first_name" />         </td>     </tr>     <tr>         <td>Age</td>         <td><asp:Textbox runat="server" id="age" /></td>     </tr>     <tr>         <td>Married?</td>         <td>         <asp:CheckBox runat="server" id="married" />         </td>     </tr>     <tr>         <td>Sex</td>         <td><asp:DropDownList runat="server" id="sex" /></td>     </tr>     <tr>         <td colspan="2" align="center">             <asp:Button runat="server" Text="Save" />         </td>     </tr> </table> </form> <asp:Label runat="server" id="output" /> </body> </html> 

As you can see, our programming code in this page is limited to the Page_Load method, which is the first method called on any ASP.NET page whenever it is loaded. Here, we check to see if the form was submitted by checking the Boolean property of the Page object, IsPostBack . If the page was not submitted (that is, this is the first time it is being viewed ), we use this opportunity to build our list box for the Sex DropDownList. In a more complicated form, you might read a list of possible values from a database in this portion of your code. If the form has been submitted ( IsPostBack is True), we simply set the value of the strMarried variable to an appropriate string depending on whether or not the Married checkbox was selected, and display our message as the value of the asp:Label control, output.

Because ASP.NET builds upon a common framework, the code segments involved in different programming languages typically bear a strong resemblance to one another. For instance, Listing 3.6 lists the C# version of the Page_Load method (the rest of the file remains the same).

Listing 3.6 Source code for readrequestCS.aspx.
 <%@ Page Language="C#" Trace="False" %> <script runat="server"> void Page_Load(Object Src, EventArgs E){     String strMarried;     if (!Page.IsPostBack){         //Build listbox -- this could be stored in a user control         sex.Items.Add("Female");         sex.Items.Add("Male");     }  else {         if (married.Checked)             strMarried = "married";         else             strMarried = "single";         output.Text = "Hello, " + first_name.Text + ".  You are a " + age.Text  + " year old, " + strMarried + " " + sex.SelectedItem.Text + ".";     } } </script> 

Line by line, this code is identical to the VB version except for minor syntactical variations. If you are a VB or VBScript programmer, you will find that C# is really not that difficult to pick up for this reason, especially if you have any C/C++/Java experience. All of the examples in this book are available in both VB and C#, although to make the most of the available space, only one or the other will be presented. In such cases, the other example will typically be available on the book's supporting Web site.

TIP

You can view this book's examples LIVE at

http://aspauthors.com/aspnetbyexample/


Validate a Form's Entries

Form validation is an important, but often neglected, part of many classic ASP applications. Typical ASP applications involve a mixture of client-side and server-side form validation techniques, and unfortunately this often results in poor validation. Also, because of the added complexity of using both client-side and server-side scripting, many developers simply don't bother with validation at all, resulting in a less satisfying user experience and frequently less data integrity. ASP.NET provides an entire suite of validation controls, which will be covered in detail in Chapter 8, "Using ASP.NET Validation Controls." Here we will demonstrate some simple form validation techniques, using classic ASP with client-side JavaScript, and ASP.NET. This example is not meant to give complete coverage to ASP.NET's validation controls; we'll only be looking at a few simple cases and building on the previous section's forms.

Our previous form included a few textboxes, a drop-down list, and a checkbox. It didn't have any validation code at all. First of all, we will update that example so that it uses client and server-side code to validate the following rules:

  • First Name must be non-blank

  • Age must be non-blank

  • Age must be numeric and above zero

  • Sex must be selected (we will make the default blank)

The client-side code required to accomplish these tasks takes the form of a validate() JavaScript method that is called whenever the user attempts to submit the form. This method uses a number of functions from a library I have developed over the years , the contents of which are beyond the scope of this book but which are available from the book's Web site. Their function should be fairly obvious from their usage in the validate() method. You can download the JavaScript file "script.js" at the book's Web site.

Note that you will never encounter the server-side validation if you are using a browser that supports JavaScript for client-side validation, because the client-side script will ensure that no bad data is ever passed to the server. However, it is good practice to always validate data server-side regardless of any client-side script, because some browsers do not support JavaScript, and because it is possible for a user to "spoof" your server by saving your form on their local machine, removing the validation code from it, and then submitting it to your server. For this reason, ASP.NET always does server-side validation when we use its validation controls, and only uses client-side validation with browsers that support it.

Listing 3.7 shows the new classic ASP page, readvalidrequest.asp, that incorporates the validation rules we have established.

Listing 3.7 Source code for readvalidrequest.asp.
 <%Option Explicit%> <% Dim first_name Dim age Dim married_check Dim married Dim sex Dim strOutput Dim strError Dim fSubmit first_name    = Request.Form("first_name") age        = Request.Form("age") married        = Request.Form("married") sex        = Request.Form("sex") If married <> "" Then     married_check="checked"     married = "married" Else     married_check = ""     married = "single" End If 'Check postback fSubmit = Request("btnSubmit") = "Save" If fSubmit Then     If first_name = "" Then         strError = strError & "You must enter a value for first name.<br>"     End If     If age = "" Then         strError = strError & "You must enter a value for age.<br>"     ElseIf Not isNumeric(age) Then         strError = strError & _ "You must enter a positive numeric value for age.<br>"     ElseIf age <= 0 Then         strError = strError & _ "You must enter a positive numeric value for age.<br>"     End If     If sex = "" Then         strError = strError & "You must select a value for sex.<br>"     End If     'Only show output if no errors     If strError = "" Then         strOutput = "Hello, " & first_name & ".  You are a " & age & " year old, " & married & " " & sex & "."     End If End If %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>ASP Forms</title> <script type="text/javascript" src="script.js"> <!-- // displays only if script file not found document.write ("JavaScript library not found."); //--> </script> <script TYPE="text/javascript"> <!-- function validate(){     with (document.form1){         if (isBlank(first_name,"You must enter a value for first name.")){             return false;         }         if (isBlank(age,"You must enter a value for age.")){             return false;         }     if (!isInteger(age.value,"You must enter a positive numeric value for age.")){             age.focus();             return false;         }         if (!isSelected(sex,"You must select a value for sex.")){             return false;         }     }     return true; } //--> </script> </head> <body> <form action="<%=Request.Servervariables("URL")%>" method="post" id="form1"     name="form1" onSubmit="return validate();"> <b><%=strError%></b> <table border="1" bgcolor="#EEEEEE">     <caption>Forms</caption>     <tr>         <td>First Name</td>         <td><input type="text" name="first_name" value="<%=first_name%>"></td>     </tr>     <tr>         <td>Age</td>         <td><input type="text" name="age" value="<%=age%>"></td>     </tr>     <tr>         <td>Married?</td>         <td><input type="checkbox" name="married" <%=married_check%>></td>     </tr>     <tr>         <td>Sex</td>         <td><select name="sex">                 <option value="">             <% If sex="male" Then %>                 <option value="female">Female</option>                 <option selected value="male">Male</option>             <% ElseIf sex="female" Then %>                 <option selected value="female">Female</option>                 <option value="male">Male</option>             <% Else %>                 <option value="female">Female</option>                 <option value="male">Male</option>             <% End If %>             </select>         </td>     </tr>     <tr>         <td colspan="2" align="center">             <input type="submit" name="btnSubmit" value="Save">         </td>     </tr> </table> </form> <%=strOutput%> </body> </html> 

Let's take a quick look at the validation we are doing in this code. We will just focus on the ASP server-side validation, because client-side JavaScript is beyond the scope of this book (and, you'll see in a moment, no longer required knowledge for client-side form validation because ASP.NET takes care of this for us). Our validation code is only done on a form submit, as demonstrated by the code snippet shown in Listing 3.8.

Listing 3.8 Source code for readvalidrequest.asp.
 If fSubmit Then     If first_name = "" Then         strError = strError & "You must enter a value for first name.<br>"     End If     If age = "" Then         strError = strError & "You must enter a value for age.<br>"     ElseIf Not isNumeric(age) Then         strError = strError & _ "You must enter a positive numeric value for age.<br>"     ElseIf age <= 0 Then         strError = strError & _ "You must enter a positive numeric value for age.<br>"     End If     If sex = "" Then         strError = strError & "You must select a value for sex.<br>"     End If     'Only show output if no errors     If strError = "" Then         strOutput = "Hello, " & first_name & ".  You are a " & age & " year old, " & married & " " & sex & "."     End If End If 

As you can see, we check first_name, age, and sex to see if they are blank ( "" ), and build an error string if they are. We also verify that age is numeric and positive, again setting appropriate error messages if we find its value to be invalid. Finally, we only output our message if there were no errors. In a more complex example, we might use this technique to limit database updates to valid values. On our HTML page, then, we display the error message as bold text, which remains unseen if no errors were encountered .

Now let's take a look at this same page in ASP.NET, using the built-in validation controls (which you will see in more detail in Chapter 8, "Using ASP.NET Validation Controls"). Listing 3.9 shows readvalidrequestVB.aspx, which uses three validation controls, the RequiredFieldValidator , RangeValidator , and ValidationSummary controls.

Listing 3.9 Source code for readvalidrequestVB.aspx.
 <%@ Page Language="VB" Trace="False" %> <script runat="server"> Sub Page_Load(Src As Object, E As EventArgs)     Dim strMarried As String     If Not Page.IsPostBack Then         'Build listbox -- this could be stored in a user control         sex.Items.Add("")         sex.Items.Add("Female")         sex.Items.Add("Male")     Else         If married.Checked Then             strMarried = "married"         Else             strMarried = "single"         End If         output.Text = "Hello, " & first_name.Text & ".  You are a " & age.Text  & " year old, " & strMarried & " " & sex.SelectedItem.Text & "."     End If End Sub </script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>ASP Forms</title> </head> <body> <form runat="server" id="form1"> <asp:ValidationSummary id="validSummary" runat="server"     headerText="***Errors On Your Form***"     showSummary="True"     displayMode="List" /> <table border="1" bgcolor="#EEEEEE">     <caption>Forms</caption>     <tr>         <td>First Name</td>         <td><asp:Textbox runat="server" id="first_name" />             <asp:RequiredFieldValidator id="required_first_name" runat="server"             controlToValidate="first_name"             errorMessage="You must enter a value for first name."             display="none" />         </td>     </tr>     <tr>         <td>Age</td>         <td><asp:Textbox runat="server" id="age" />             <asp:RequiredFieldValidator id="required_age" runat="server"             controlToValidate="age"             errorMessage="You must enter a value for age."             display="none" />             <asp:RangeValidator id="required_age_range" runat="server"             controlToValidate="age"             type="Integer"             minimumValue="1"             maximumValue="150"             errorMessage="You must enter a positive number value for age."             display="none" />         </td>     </tr>     <tr>         <td>Married?</td>         <td>         <asp:CheckBox runat="server" id="married" />         </td>     </tr>     <tr>         <td>Sex</td>         <td><asp:DropDownList runat="server" id="sex" />             <asp:RequiredFieldValidator id="required_sex" runat="server"             controlToValidate="sex"             errorMessage="You must select a value for sex."             display="none" />         </td>     </tr>     <tr>         <td colspan="2" align="center">             <asp:Button runat="server" Text="Save" />         </td>     </tr> </table> </form> <asp:Label runat="server" id="output" /> </body> </html> 

You can see that there is no difference in our VB code for this page versus readrequestVB.asp, except that we have added a blank entry to our Sex DropDownList in the Page_Load (because not much has changed, the C# code will not be displayed, but is available on the book's support Web site, at http://aspauthors.com/aspnetbyexample/). The real differences are in the HTML code, with the addition of a few more controls.

The first control we encounter as we move down the page is the ValidationSummary control. This control is used to display summarized results of validation, and mirrors the way in which our ASP page's server-side validation was displayed:

 <asp:ValidationSummary id="validSummary" runat="server" headerText="***Errors On Your Form***" showSummary="True" displayMode="List" /> 

This control is fairly intuitive to use. HeaderText is displayed as the header for the error listing. Setting showSummary to True ensures that it is displayed if errors are found. By default errors are listed in a bulleted list, but in this example we are listing them separated by <br> tags instead by using the displayMode of "List".

The next control we use is the RequiredFieldValidator :

 <asp:RequiredFieldValidator id="required_first_name" runat="server" controlToValidate="first_name" errorMessage="You must enter a value for first name." display="none" /> 

This is a very simple control, which merely ensures that the user enters something into a form field. The display property is used to determine how the control is displayed on the screen. In our case, because we are using the ValidationSummary control for display, our individual validation controls will all use a display of none.

Finally, to ensure that the age entered is a positive number, we use a RangeValidator :

 <asp:RangeValidator id="required_age_range" runat="server" controlToValidate="age" type="Integer" minimumValue="1" maximumValue="150" errorMessage="You must enter a positive number value for age." display="none" /> 

This requires three new properties to be set; type , minimumValue , and maximumValue . It ensures that the linked control (in our case, age) falls within the range specified by minimumValue and maximumValue , using the comparison technique listed in the type parameter. Note that it is not sufficient to provide only a minimumValue or a maximumValue for this control, so in enforcing our rule of positive numbers for age, we were forced to specify an upper limit as well. If I had really wanted to only specify a lower limit, I could have used a custom validation control for that purpose.

The Login Page

One of the more common features of interactive Web sites today is the login screen. Often this form will reside in the corner of a site's main page, or will appear whenever a secure page is requested and the user has not authenticated. The simplest way to restrict access to certain pages in Classic ASP is to use a login include file, and simply include the file on those pages that require authentication.

For this first example, we have two Classic ASP pages, a page that requires users to register before viewing it (secret.asp), and a login page that is implemented using an include file (login_simple.asp). This example happens to use cookies, but you could use any of the state management techniques discussed earlier just as easily. Remember, though, that if you use session variables, you won't be able to transfer state between ASP and ASP.NET pages.

NOTE

You can run these examples live on this book's support Web site, at

http://aspauthors.com/aspnetbyexample/ch03/


The source code for secret.asp shows this very simple page, the most important part of which is the second line, where it includes the login code (see Listing 3.10).

Listing 3.10 Source code for secret.asp.
 <% OPTION EXPLICIT %> <!-- #INCLUDE FILE="login_simple.asp" --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>Login Test</title> </head> <body> <b>Top Secret Page</b><br> <%=Request.Cookies("Username")%> Logged In! </body> </html> 

As you can see, the page we want to protect simply uses an include statement to add the login functionality to the page. Because it uses an in-memory cookie, which lasts until the user's browser is closed, the login is only required the first time the user accesses this or any other protected page on this site.

The login include file, login_simple.asp, is really fairly simple, but because it contains three separate HTML pages within it, it is fairly long. Don't let that intimidate you; there are less than 30 actual lines of code! Listing 3.11 shows the complete file.

Listing 3.11 Source code for login_simple.asp.
 <% If Request.Cookies("ASPLogin") <> "True" Then     Call Login() End If Sub Login ()     Dim cmd     Dim sql     Dim connstring     Dim fValidLogin     fValidLogin = False     connstring = "DSN=myDSN;UID=user;pwd=pass"     If Request.Form("btnSubmit") <> "Submit Authorization" Then     'Show login form %> <html> <head> <title>Login</title> </head> <body bgcolor="#FFFFFF" link="#010187" vlink="#010187" alink="#010187" onLoad="document.Form1.frmUserID.focus();"> <center> (Note: You can test this form by using "user1" as the username and password) <table border="2" cellpadding="6" width="80%"> <form action="<% = Request.ServerVariables("URL")%>?<%=Request.ServerVariables  ("QUERY_STRING")%>" method="POST" Name="Form1"> <input type="hidden" name="frmLogin" value="true">     <tr>         <td align="right"><font size="2"         face="Tahoma">User ID:</font></td>         <td><input type="text" size="20"         name="frmUserID" maxlength="10"></td>     </tr>     <tr>         <td align="right"><font size="2"         face="Tahoma">Password:</font></td>         <td><input type="password"         size="20" name="frmUserPass"></td>     </tr>     <tr>         <td>&nbsp;</td>         <td><input type="submit" name="btnSubmit"         value="Submit Authorization"></td>     </tr> </form> </table> </center> </body> </html> <%         Response.End     Else         Set cmd = Server.CreateObject("ADODB.Command")         With cmd             .ActiveConnection = connstring             .CommandText = "sp_AuthenticateUser"             .CommandType = adCmdStoredProc             'Add Parameters             .Parameters.Append .CreateParameter("@UserID", adVarChar, adParamInput, 20, Request.Form("frmUserID"))             .Parameters.Append .CreateParameter("@Password", adVarChar, adParamInput, 20, Request.Form("frmUserPass"))             'Add Output Parameter             .Parameters.Append .CreateParameter("@IsValid, adTinyInt, adParamOutput, , 0)             'Execute the function             .Execute , , adExecuteNoRecords             If IsNull(.Parameters("@IsValid).Value) Then                 fValidLogin = False             Else                 fValidLogin = CInt(.Parameters("@IsValid).Value) = 1             End If         End With         Set cmd = Nothing         If fValidLogin Then             'Set Cookie             Response.Cookies("ASPLogin") = "True"             Response.Cookies("Username") = Request.Form("frmUserID")         Else         'Show Invalid Login screen. %> <html> <head>     <title>Login Failure</title> </head> <body bgcolor="#FFFFFF" link="#010187" vlink="#010187" alink="#010187"> <center>     <table border="2" cellpadding="6" width="80%">         <tr>             <td><center>             <font size="2" face="Tahoma">UserID <%=request.form("frmUserID")%>  and the password you provided                 is not a valid user/password combination. <br>             <a href="<% = Request.ServerVariables("URL")%>"> Click here to retry...</center></td>         </tr>     </table> </center> </body> </html> <%             Response.End         End If 'Check user exists     End If End Sub %> 

Now when you try to access secret.asp, you will first be presented with a simple login form (Figure 3.3). When you enter a valid username and password, though, you are authorized to see the actual page, which now knows who you are based on your login. The login include file calls a stored procedure, sp_AuthenticateUser , which checks the username and password against a database and returns an output parameter, @is_valid , which is either 1 if the user is valid or 0 otherwise. This stored procedure is shown in Listing 3.12.

Figure 3.3. Login screen and secret.asp after successful login.

Listing 3.12 Source code for sp_AuthenticateUser .
 CREATE PROCEDURE dbo.sp_AuthenticateUser   @UserID   varchar(20),   @Password varchar(20) ,   @IsValid int output AS     BEGIN         if (select count(*) from aspuser             where username= @UserID and password = @Password ) = 1             set @IsValid = 1         else             set @IsValid = 0         return     END 

The final result is a simple login page that prevents unauthorized users from seeing our secret page. Figure 3.3 demonstrates the login form and the secret page that is displayed when a valid login is provided.

Now let's see how we would do this in ASP.NET. Although you can still use include files in ASP.NET, we're going to use a User control, which works much better than an ASP include file for several reasons. User controls can accept parameters, can be dynamically chosen at runtime, use their own variable scope, and can access any page-level variables. In effect, they have all of the advantages ASP includes with none of the disadvantages (like no runtime access and duplicate declarations if you include them twice).

Let's take a look at our secret page again, this time written in ASP.NET (secret.aspx, see Listing 3.13), and our login user control (login.ascx, see Listing 3.14). In this case, we have added a little more code to the .aspx page than we did to our .asp page, in order to control whether or not the .aspx page displays. By default, User controls are displayed along with the rest of the page, and because ASP.NET is event-driven, not interpreted top to bottom like an ASP page, it is more difficult to simply stop execution after the login form. So we use some code in the page load event to determine whether or not to display the login or the main page contents. This is not ideal, and we will look at another way to handle logins in ASP.NET next.

Listing 3.13 Source code for secret.aspx.
 <%@ Page Language="C#" Debug="true" Trace="False" %> <%@ Register TagPrefix="LoginModule" TagName="LoginModule" Src="login.ascx" %> <script language="C#" runat=server> protected void Page_Load(Object sender, EventArgs E) {     // Get username to display     if (Request.Cookies["UserName"] == null){         display2.Text  = string.Empty;         Login.Visible = true;         main.Visible = false;     }  else {         display2.Text = Request.Cookies["AspxUserName"].Value;     } } </script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/  REC-html40/loose.dtd"> <html> <head> <title>Login Test</title> </head> <body> <form id="form1" runat="server"> <asp:Panel id="Login" MaintainState="true" visible="false"     runat="server">     <LoginModule:LoginModule runat="server"/> </asp:Panel> <span id="main" runat="server"> <b>Top Secret Page</b><br> <asp:Label id="display" runat="server" /> <asp:Label id="display2" runat="server" />  Logged In! </span> </form> </body> </html> 
Listing 3.14 Source code for login.ascx.
 <%@ Import Namespace="System.Data.SqlClient" %> <%@ Import Namespace="System.Data" %> <script language="C#" runat=server>     public String RedirectPage ="default.aspx";     bool Authenticate(String user, String pass) {                bool authenticated = false;                try {                               SqlConnection myConnection = new             SqlConnection(ConfigurationSettings.AppSettings["connectionString"]);                               SqlCommand myCommand = new SqlCommand (  "sp_AuthenticateUser", myConnection);                               myCommand.CommandType = CommandType.StoredProcedure ;                          // Add Parameters                       SqlParameter myUserId = new SqlParameter("@UserId", SqlDbType.  VarChar, 20);                       myUserId.Value =  user.Trim();                       myCommand.Parameters.Add(myUserId);                       SqlParameter myPassword = new SqlParameter("@Password",SqlDbType.  VarChar, 15);                       myPassword.Value = pass.Trim();                       myCommand.Parameters.Add(myPassword);                       SqlParameter IsValid = new SqlParameter("@IsValid",SqlDbType.Int);                       IsValid.Direction = ParameterDirection.Output;                       myCommand.Parameters.Add(IsValid);                       // Execute the Query                       myConnection.Open();                       myCommand.ExecuteNonQuery();                       myConnection.Close();                       if ( ((int)IsValid.Value) == 1)                           authenticated =true;                }                catch(Exception e) {                       Response.Write("Auth Exception: " + e.ToString());                }                return authenticated;     }     private void SubmitBtn_Click(Object sender, EventArgs e) {        if (Authenticate(UserName.Text, Password.Value)) {                       System.Web.Security.FormsAuthentication.SetAuthCookie (UserName.  Text, true);                       Response.Cookies["AspxUserName"].Value = UserName.Text;                       Response.Redirect("secret.aspx");        }        else {            ErrorMsg.Visible = true;            //Response.Redirect(RedirectPage);        }     } </script> <!--BEGIN LOGIN MODULE--> <table border="2" cellpadding="6" width="80%"> <input type="hidden" name="frmLogin" value="true">     <tr>         <td align="right"><font size="2"         face="Tahoma">User ID:</font></td>         <td><asp:textbox id="UserName" size="14" runat="server" /></td>     </tr>     <tr>         <td align="right"><font size="2"         face="Tahoma">Password:</font></td>         <td><input id="Password" type="password" size="14" runat="server"></td>     </tr>     <tr>         <td>&nbsp;</td>         <td><input type="submit"  value="     Sign In     "  onServerClick="SubmitBtn_Click" runat=server /></td>     </tr>     <tr>         <td colspan=2 align=center>            <span id="ErrorMsg" style="color:black;font:8pt verdana, arial" Visible=false  runat=server>               <b>Invalid Account Name or Password!</b>            </span>         </td>     </tr> </table> <!--END LOGIN MODULE--> 

The login.ascx file uses the same sp_AuthenticateUser stored procedure as the login_simple.asp include file, and sets a cookie if the user is valid. The secret.aspx file then checks to see if this cookie has been provided, and displays the secret contents if it has. The login.ascx file also accepts a parameter, RedirectPage , which sets the location to redirect users to if their login fails.

Although the function of this ASP.NET login page is very similar to the ASP one, its implementation is not nearly as elegant. With the ASP include file, all that was required was to add one line to a page, the include statement, to protect it. With our ASP.NET solution, we need to add quite a bit more code to each page we want to protect. There has to be a better way!

In ASP.NET, the preferred way to configure security is through the web.config configuration file. In this file, you can specify all pages in the application that require a user login, specify how authentication is to be performed, and where to direct users who need authenticated. This makes it very easy to control access to your entire application through a single interface, instead of having to open many individual pages to make them require authentication. Using this technique, along with other application-level configuration settings, is covered in Chapter 10, "ASP.NET Applications."

View Results of Database Query

The last example we are going to look at in this chapter is how to view the results of a database query. Once more, we'll examine a simple ASP page that accomplishes this task, and then we will look at an ASP.NET page that does the same thing, using both VB and C#. For this example, we are going to produce a table that lists country names and their abbreviations. The source of the data is a table in a SQL server database, t_country, which has country_name and abbreviation columns .

Listing 3.15 shows countries .asp, a simple Web page that displays the results of a query against the t_country table.

Listing 3.15 Source code for countries.asp.
 <%Option Explicit%> <% Dim strSql Dim objRs Dim objConn Dim I Set objRs = Server.CreateObject("ADODB.Recordset") Set objConn = Server.CreateObject("ADODB.Connection") %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>Countries</title> </head> <body> <table cellspacing="0" cellpadding="1" rules="all" bordercolor="Black" border="1" style="background-color:#EEEEEE;border-color:Black;font-family: Verdana;font-size:8pt;width:700px;border-collapse:collapse;"> <% strSql = "SELECT country_name as 'Country Name', abbreviation as 'Abbreviation' " & _         " FROM t_country ORDER BY country_name" objConn.Open Application("aspauthors_ConnectionString") objRs.Open strSql, objConn If Not objRs.EOF Then     'Header     Response.Write "<tr bgcolor=""#CCCCCC"">"     For I = 0 To objRs.Fields.Count - 1         Response.Write "<th>" & objRs.Fields(I).Name & "</th>"     Next     Response.Write "</tr>" End If While Not objRs.EOF     Response.Write "<tr>"     For I = 0 To objRs.Fields.Count - 1         Response.Write "<td>" & objRs.Fields(I).Value & "</td>"     Next     Response.Write "</tr>"     objRs.MoveNext End objRs.Close objConn.Close Set objRs = Nothing Set objConn = Nothing %> </table> </body> </html> 

This is pretty basic ASP code. For this example, I chose to use a For loop to iterate through the different fields in order to display the header values and data. In this way, I could reuse all of the code used to output the table rows regardless of the query used to generate the ouput. The results of this query are displayed in Figure 3.4.

Figure 3.4. Countries.asp.

To accomplish the same thing using ASP.NET, we will take advantage of the DataGrid control. You will learn more about the DataGrid control in the next few chapters, but it is very useful for displaying (and modifying) data in HTML tables. Listing 3.16 displays countriesVB.aspx, and Listing 3.17 displays the script portion of countriesCS.aspx, the C# version of our ASP.NET page.

Listing 3.16 Source code for countriesVB.aspx.
 <%@ Page Language="VB" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <script language="VB" runat="server">     Sub Page_Load(Src As Object, E As EventArgs)         Dim MyConnection As SqlConnection         Dim MyCommand As SqlCommand                myConnection = new SqlConnection(ConfigurationSettings.AppSettings(  "connectionString"))                myCommand = new SqlCommand("SELECT country_name as 'Country Name', " & _                        "abbreviation as 'Abbreviation' FROM t_country " & _                        "ORDER BY country_name", myConnection)                myCommand.Connection.Open()         MyDataGrid.DataSource=myCommand.ExecuteReader(CommandBehavior. CloseConnection)         MyDataGrid.DataBind()     End Sub </script> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"             "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>Countries</title> </head> <body>   <ASP:DataGrid id="MyDataGrid" runat="server"     Width="700"     BackColor="#eeeeee"     BorderColor="black"     ShowFooter="false"     CellPadding="1"     CellSpacing="0"     Font-Name="Verdana"     Font-Size="8pt"     HeaderStyle-BackColor="#cccccc"     MaintainState="false"   /> </body> </html> 
Listing 3.17 Source code for countriesCS.aspx.
 <%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <script language="C#" runat="server">     protected void Page_Load(Object Src, EventArgs E)     {                SqlConnection myConnection = new SqlConnection(ConfigurationSettings.  AppSettings["connectionString"]);                SqlCommand myCommand =                       new SqlCommand("SELECT country_name as 'Country Name', " +                   "abbreviation as 'Abbreviation' FROM t_country " +                   "ORDER BY country_name", myConnection);                 myCommand.Connection.Open();         MyDataGrid.DataSource=myCommand.ExecuteReader(CommandBehavior.  CloseConnection);         MyDataGrid.DataBind();     } </script> 

In both of these ASP.NET examples, we see that the code involved to produce the same output as the ASP code is less, and there is no script interlaced with our HTML. This provides a much more object oriented, event driven programming experience than the serial processing of ASP scripts. These examples take advantage of imported libraries, SQL data objects, datasets, and datagrids . All of these concepts will be discussed further in the rest of the book, and are presented here as a primer.

I l @ ve RuBoard


Asp. Net. By Example
ASP.NET by Example
ISBN: 0789725622
EAN: 2147483647
Year: 2001
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net