Validation Controls Dr. Awad Khalil Computer Science & Engineering Department AUC Regular Expressions and Class Regex Regular expressions are specially formatted strings used to find patterns in text. They can be useful during information validation, to ensure that data in a particular format. For example, a ZIP code must consist of five digits, and a last name must start with a capital letter. Compilers use regular expressions to validate the syntax of programs. If the program code does not match the regular expression, the compiler indicates that there is syntax error. The .NET Framework provides several classes to help developers recognize and manipulate regular expressions. Web Controls Description Checks that the user does not leave a field blank. CompareValidator Compares an input value with another value. The value being compared to may be another control’s input value. RangeValidator Checks that a user’s entry is within a specified range. RegularExpressionValidator Checks that the entry matches a regular expression pattern. ValidationSummary Displays the validation errors for all the validation controls on a page. Validation server controls. Server Control RequiredFieldValidator Regular Expressions and Class Regex Class Regex (of the System.Text.RegularExpressions namespace) represents an immutable regular expression. Regex method Match returns an object of class Match that represents a single regular expression match. Regex also provides method Matches, which finds all matches of a regular expression in an arbitrary string and returns an object of the class MatchCollection object containing all the Matches. A collection is data structure, similar to an array and can be used with a foreach statement to iterate through the collection’s elements. Regular Expressions Character Classes The following table specifies some character classes that can be used with regular expressions. Please do not confuse a character class with C# class declaration. A character class is simply an escape sequence that represents a group of characters that might appear in a string. A word character is any alphanumeric character or underscore. A whitespace character is a space, a tab, a carriage return, a newline or a form feed. A digit is any numeric character. Regular expressions are not limited to the character classes, they can use other notations to search for complex patterns in strings. Character Class Matches Character Class Matches \d Any digit \D Any non-digit \w Any word character \W Any non-word character \s Any whitespace \S Any non-whitespace Regular Expression Example The following program tries to match birthdays to a regular expression. Just for demonstration purposes, the expression matches only birthdays that do not occur in April and that belong to people whose names begin with “J”. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. // RegexMatches.cs // Demonstrating Class Regex. using System; using System.Text.RegularExpressions; class RegexMatches { public static void Main() { // create regular expression Regex expression = new Regex( @"J.*\d[0-35-9]-\d\d-\d\d" ); string string1 = "Jane's Birthday is 05-12-75\n" + "Dave's Birthday is 11-04-68\n" + "John's Birthday is 04-28-73\n" + "Joe's Birthday is 12-17-77"; // match regular expression to string and // print out all matches foreach ( Match myMatch in expression.Matches( string1 ) ) Console.WriteLine( myMatch ); } // end method Main } // end class RegexMatches Examining RegexMatches.cs Lines 11-12 create a Regex object and pass a regular expression pattern string to the Regex constructor. Note that we precede the string with @. Recall that backslashes within the double quotation marks following the @ character are regular backslash characters, not the beginning of escape sequences. To define the regular expression without prefixing @ to the string, you would need to escape every backslash character, as in “J.*\\d[0-35-9]-\\d\\d-\\d\\d” which makes the regular expression more difficult to read. Examining RegexMatches.cs The first character in the regular expression, “J”, is a literal character. Any string matching this regular expression is required to start with “J”. In a regular expression, the dot character “.” matches any single character except a newline character. When the dot character is followed by an asterisk, as in “.*” , the regular expression matches any number of unspecified characters except newlines. In general, when the operator “*” is applied to a pattern, the pattern will match zero or more occurrences. Examining RegexMatches.cs By contrast, applying the operator “+” to a pattern causes the pattern to match one or more occurrences. For example both “A*” and “A+” will match “A” but only “A*” will match an empty string. “\d” matches any numeric digit . To specify sets of characters other than those that belong to a predefined character class, characters can be listed in square brackets, []. For example, the pattern “[aeiou]” matches any vowel. Ranges of characters are represented by placing a dash (-) between two characters. In the example, “[0-35-9]” matches only digits in the ranges specified by the pattern - i.e., any digit between 0 and 3 or between 5 and 9; therefore, it matches any digit except 4. You can also specify that a pattern should match anything other than the characters in the brackets. To do so, place ^ as the first in the brackets. It is important to note that “[^4]” is not the same as “[0-35-9]” ; “[^4]” matches any non-digit and digits other than 4. Examining RegexMatches.cs Although the “-” character indicates a range when it is enclosed in square brackets, instances of the “-” character outside grouping expressions are treated as literal characters. Thus, the regular expression in line 12 searches for a string that starts with the letter “J”, followed by any number of characters (except newline), followed by a dash, another two-digit number (of which the second digit cannot be 4), followed by a dash, another two-digit number, a dash and another two-digit number. Lines 21-22 use a foreach statement to iterate through the MatchCollection returned by the expression object’s Matches method, which received string1 as an argument. The elements in the MatchCollection are Match objects, so the foreach statement declares variable myMatch to be type Match. For each Match, line 22 outputs the text that matched the regular expression. Examining RegexMatches.cs Quantifiers The asterisk (*) in line 12 is more formally called a quantifier. The following table lists various quantifiers that you can place after a pattern in a regular expression and the purpose of each quantifier. All quantifiers are greedy – they will match as many occurrences of the pattern as possible until the pattern fails to make a match. If a quantifier is followed by a question mark (?), the quantifier becomes lazy and will match as few occurrences as possible as long as there is a successful match. Quantifier Matches * Matches zero or more occurrences of the preceding pattern. + Matches one or more occurrences of the preceding pattern ? Matches zero or one occurrences of the preceding pattern. {n} Matches exactly n occurrences of the preceding pattern. {n,} Matches at least n occurrences of the preceding pattern. {n,m} Matches between n and m (inclusive) occurrences of the preceding pattern. Validating User Input Using Regular Expressions The following Windows application uses regular expressions to validate name, address and telephone number information input by a user. 1. // Validate.cs 2. // Validate user information using regular expressions. 3. using System; 4. using System.Text.RegularExpressions; 5. using System.Windows.Forms; 6. 7. public partial class ValidateForm : Form 8. { 9. // default constructor 10. public ValidateForm() 11. { 12. InitializeComponent(); 13. } // end constructor 14. 15. // handles OkButton Click event 16. private void okButton_Click( object sender, EventArgs e ) 17. { 18. // ensures no TextBoxes are empty 19. if ( lastNameTextBox.Text == "" || firstNameTextBox.Text == "" || 20. addressTextBox.Text == "" || cityTextBox.Text == "" || 21. stateTextBox.Text == "" || zipCodeTextBox.Text == "" || 22. phoneTextBox.Text == "" ) 23. { 24. // display popup box 25. MessageBox.Show( "Please fill in all fields", "Error", 26. MessageBoxButtons.OK, MessageBoxIcon.Error ); 27. lastNameTextBox.Focus(); // set focus to lastNameTextBox 28. return; 29. } // end if 30. 31. // if last name format invalid show message 32. if ( !Regex.Match( lastNameTextBox.Text, 33. "^[A-Z][a-zA-Z]*$" ).Success ) 34. { 35. // last name was incorrect 36. MessageBox.Show( "Invalid last name", "Message", 37. MessageBoxButtons.OK, MessageBoxIcon.Error ); 38. lastNameTextBox.Focus(); 39. return; 40. } // end if 41. 42. // if first name format invalid show message 43. if ( !Regex.Match( firstNameTextBox.Text, 44. "^[A-Z][a-zA-Z]*$" ).Success ) 45. { 46. // first name was incorrect 47. MessageBox.Show( "Invalid first name", "Message", 48. MessageBoxButtons.OK, MessageBoxIcon.Error ); 49. firstNameTextBox.Focus(); 50. return; 51. } // end if 53. // if address format invalid show message 54. if ( !Regex.Match( addressTextBox.Text, 55. @"^[0-9]+\s+([a-zA-Z]+|[a-zA-Z]+\s[a-zA-Z]+)$" ).Success ) 56. { 57. // address was incorrect 58. MessageBox.Show( "Invalid address", "Message", 59. MessageBoxButtons.OK, MessageBoxIcon.Error ); 60. addressTextBox.Focus(); 61. return; 62. } // end if 63. 64. // if city format invalid show message 65. if ( !Regex.Match( cityTextBox.Text, 66. @"^([a-zA-Z]+|[a-zA-Z]+\s[a-zA-Z]+)$" ).Success ) 67. { 68. // city was incorrect 69. MessageBox.Show( "Invalid city", "Message", 70. MessageBoxButtons.OK, MessageBoxIcon.Error ); 71. cityTextBox.Focus(); 72. return; 73. } // end if 74. 75. // if state format invalid show message 76. if ( !Regex.Match( stateTextBox.Text, 77. @"^([a-zA-Z]+|[a-zA-Z]+\s[a-zA-Z]+)$" ).Success ) 78. { 79. // state was incorrect 80. MessageBox.Show( "Invalid state", "Message", 81. MessageBoxButtons.OK, MessageBoxIcon.Error ); 82. stateTextBox.Focus(); 83. return; 84. } // end if 85. 86. // if zip code format invalid show message 87. if ( !Regex.Match( zipCodeTextBox.Text, @"^\d{5}$" ).Success ) 88. { 89. // zip was incorrect 90. MessageBox.Show( "Invalid zip code", "Message", 91. MessageBoxButtons.OK, MessageBoxIcon.Error ); 92. zipCodeTextBox.Focus(); 93. return; 94. } // end if 95. 96. // if phone number format invalid show message 97. if ( !Regex.Match( phoneTextBox.Text, 98. @"^[1-9]\d{2}-[1-9]\d{2}-\d{4}$" ).Success ) 99. { 100.// phone number was incorrect 101.MessageBox.Show( "Invalid phone number", "Message", 102.MessageBoxButtons.OK, MessageBoxIcon.Error ); 103.phoneTextBox.Focus(); 104.return; 105.} // end if 106. 107.// information is valid, signal user and exit application 108.this.Hide(); // hide main window while MessageBox displays 109.MessageBox.Show( "Thank You!", "Information Correct", 110.MessageBoxButtons.OK, MessageBoxIcon.Information ); 111.Application.Exit(); 112.} // end method okButton_Click 113.} // end class ValidateForm Examining Validate.cs When a user clicks the OK button, the program checks to make sure that none of the fields is empty (lines 19-22). If one or more fields are empty, the program displays a message to the user (lines 25-26) that all fields must be filled in before the program can validate the input information. Line 27 calls lastNameTextBox’s Focus method to place the cursor in the lastNameTextBox. The program then exits the event handler (line 28). If there are no empty fields, lines 32-105 validate the user input. Lines 32-40 validate the last name by calling static method Match of class Regex, passing both the string to validate and the regular expression as arguments. Method Match returns a Match object. This object contains a Success property that indicates whether method Match’s first argument matched the pattern specified by the regular expression in the second argument. Examining Validate.cs If the value of Success is False (i.e., there was no match), lines 36-37 display an error message, line 38 sets the focus back to the lastNameTextBox so that user can retype the input and line 39 terminates the event handler. If there is a match, the event handler proceeds to validate the first name. this process continues until the event handler validates the user input in all the TextBoxes or until a validation fails. If all of the fields contain valid information, the program displays a message dialog stating this, and the program exits when the user dismisses the dialog. Examining Validate.cs In the previous example, we searched a string for substrings that matched a regular expression. In this example, we want to ensure that the entire string in each TextBox conforms to a particular regular expression. For example, we want to accept “Khalil” as a last name , but not “9@Khalil#”. In a regular expression that begins with a “^” character and ends with a “$” character, the characters “^” and “$” represent the beginning and end of a string, respectively. Those characters force a regular expression to return a match only if the entire string being processed matches the regular expression. The regular expression in line 33 uses the square bracket and range notation to match an uppercase first letter, followed by letters of any case – a-z matches any lowercase letter, and A-Z matches any uppercase letter. The * quantifier signifies that the second range of characters may occur zero or more times in the string. Thus, this expression matches any string consisting of one uppercase letter, followed by zero or more additional characters. Examining Validate.cs The notation \s matches a single whitespace character (lines 55, 66 and 77). The expression \d{5}, used in the Zip (zip code) field, matches any five digits (line 87). Note that without the “^” and “$” characters, the regular expression would match any five consecutive digits in the string. By including the “^” and “$” characters, we ensure that only five-digit zip codes are allowed. The character “|” (lines 55, 66 and 77) matches the expression to its left or the expression to its right. For example, Hi (John | Jane) matches both Hi John and Hi Jane. In line 55, we use the character “|” to indicate that the address can contain a word of one or more characters or a word of one or more characters followed by a space and another word of one or more characters. Note the use of parenthesis to group parts of the regular expression. Quantifiers may be applied to patterns enclosed in parenthesis to create more complex regular expressions. Examining Validate.cs The Last name and First name fields both accept strings of any length that begin with an uppercase letter. The regular expression for the Address field (line 55) matches a number of at least one digit, followed by a space and then either one or more letters or else one or more letters followed by a space and another series of one or more letters. Therefore, “10 Elhegaz” and “10 Elhegaz Street” are both valid addresses. As currently formed, the regular expression in line 55 does not match an address that does not start with a number or that has more than two words. The regular expression for the City (line 66) and State (line 77) fields match any word of at least one character or, alternatively, any two words of at least one character if the words are separated by a single space. This means both Cairo and New Cairo would match. Again, these regular expressions would not accept names that have more than two words. Examining Validate.cs The regular expression for the Zip code field (line 87) ensures that the zip code is a five-digit number. The regular expression for the Phone field (line 98) indicates that the phone number must be of the form xxx-yyy-yyyy, where the xs represent the area code and the ys the number. The first x and the first y cannot be zero, as specified by the range [1-9] in each case. Regex methods Replace and Split Sometimes it is useful to replace parts of one string with another or to split a string according to a regular expression. For this purpose, Regex class provides static and instance versions of methods Replace and Split, which are demonstrated in the following example. 1. // RegexSubstitution.cs 2. // Using Regex method Replace. 3. using System; 4. using System.Text.RegularExpressions; 5. 6. class RegexSubstitution 7. { 8. public static void Main() 9. { 10. string testString1 = 11. "This sentence ends in 5 stars *****"; 12. string output = ""; 13. string testString2 = "1, 2, 3, 4, 5, 6, 7, 8"; 14. Regex testRegex1 = new Regex( @"\d" ); 15. string[] result; 17. Console.WriteLine( "Original string: " + 18. testString1 ); 19. testString1 = Regex.Replace( testString1, @"\*", "^" ); 20. Console.WriteLine( "^ substituted for *: " + testString1 ); 21. testString1 = Regex.Replace( testString1, "stars", 22. "carets" ); 23. Console.WriteLine( "\"carets\" substituted for \"stars\": " + 24. testString1 ); 25. Console.WriteLine( "Every word replaced by \"word\": " + 26. Regex.Replace( testString1, @"\w+", "word" ) ); 27. Console.WriteLine( "\nOriginal string: " + testString2 ); 28. Console.WriteLine( "Replace first 3 digits by \"digit\": " + 29. testRegex1.Replace( testString2, "digit", 3 ) ); 30. Console.Write( "string split at commas [" ); 31. 32. result = Regex.Split( testString2, @",\s" ); 33. 34. foreach ( string resultString in result ) 35. output += "\"" + resultString + "\", "; 36. 37. // Delete ", " at the end of output string 38. Console.WriteLine( output.Substring( 0, output.Length - 2 ) + "]" ); 39. } // end method Main 40. } // end class RegexSubstitution Examining RegexSubdtitution.cs Method Replace replaces text in a string with new text wherever the original string matches a regular expression. We use two versions of this method in our example. The first version (line 19) is static and takes three parameters – the string to modify, the string containing the regular expression to match and the replacement string. Here, Replace replaces every instance of “*” in testString with “^”. Note that the regular expression (@”\*”) precedes character * with a backslash, \. Normally, * is a quantifier indicating that a regular expression should match any number of occurrences of a preceding pattern. However, in line 19, we want to find all occurrences of the literal characters *; to do this, we must escape character * with character \. By escaping a special regular expression character with a \, we tell the regular-expression matching engine to find the actual character * rather than use it as a quantifier. Examining RegexSubdtitution.cs The second version of method Replace (line 29) is an instance method that uses the regular expression passed to the constructor for testRegex1 (line 14) to perform the replacement operation. Line 14 instantiates testRegex1 with argument @”\d”. The call to instance method Replace in line 29 takes three arguments – a string to modify, a string containing the replacement text and an int specifying the number of replacements to make. In this case, line 29 replaces the first three instances of a digit (“\d”) in testString2 with the text “digit”. Method Split divides a string into several substrings. The original string is broken at delimiters that match a specified regular expression. Method Split returns an array containing the substrings. In line 32, we use the static version of method Split to separate a string of comma-separated integers. Examining RegexSubdtitution.cs The first argument is the string to split; the second argument is the regular expression that represents the delimiter. The regular expression @”,\s” separates the substrings at each comma. By matching any whitespace characters (\s* in the regular expression), we eliminate extra spaces from the resulting substrings. Validation Controls (Validators) in ASP.NET A validation control (or validator) determines whether the data in another Web control is in the proper format. For example, validation could determine whether a user has provided information in a required field or whether a ZIP –code field contains exactly five digits. Validators provide a mechanism for validating user input on the client. When the XHTML for our page is created, the validator is converted into ECMAScript that performs the validation. ECMAScript (commonly known as JavaScript) is a scripting language that enhances the functionality and appearance of Web pages. ECMAScript is typically executed on the client. Some clients do not support scripting or disable scripting. However, for security reasons, validation is always performed on the server – whether or not the script executes on the client. Validating Input on a Web Form The following example prompts the user to enter a name, e-mail address and phone number . A Web site could use a form like this to collect contact information from site visitors. After the user enters any data, but before the data is sent to the Web server, validators ensure that the user entered a value in each field and that the e-mail address and phone number values are in an acceptable format. In this example, (002) 123-4567, 002-123-4567, 123-4567 and (012) 123-4567 are all considered valid phone numbers. Once the data is submitted, the Web server responds by displaying an appropriate message and an XHTML table repeating the submitted information. Note that a real business application would typically store the submitted data in a database or in a file on the server. We simply send the data back to the form to domenstrate that the server received the data. Validation.aspx 1. <%-- Validation.aspx --%> 2. <%-- Form that demonstrates using validators to validate user input. --%> 3. <%@ Page Language="C#" AutoEventWireup="true" 4. CodeFile="Validation.aspx.cs" Inherits="Validation" %> 5. 6. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 7. "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 8. 9. <html xmlns="http://www.w3.org/1999/xhtml" > 10. <head id="Head1" runat="server"> 11. <title>Demonstrating Validation Controls</title> 12. </head> 13. <body> 14. <form id="form1" runat="server"> 15. <div> 16. Please fill out the following form.<br /> 17. <em>All fields are required and must 18. contain valid information.</em><br /> 19. <br /> 20. <table> 21. <tr> 22. <td style="width: 100px" valign="top">Name:</td> 23. <td style="width: 450px" valign="top"> 24. <asp:TextBox ID="nameTextBox" runat="server"> 25. </asp:TextBox><br /> 26. <asp:RequiredFieldValidator ID="nameInputValidator" 27. runat="server" ControlToValidate="nameTextBox" 28. ErrorMessage="Please enter your name." 29. Display="Dynamic"></asp:RequiredFieldValidator> 30. </td> 31. </tr> 32. <tr> 33. <td style="width: 100px; height: 64px;" valign="top"> 34. E-mail address:</td> 35. <td style="width: 450px; height: 64px;" valign="top"> 36. <asp:TextBox ID="emailTextBox" runat="server"> 37. </asp:TextBox> 38. &nbsp;e.g., user@domain.com<br /> 39. <asp:RequiredFieldValidator ID="emailInputValidator" 40. runat="server" ControlToValidate="emailTextBox" 41. ErrorMessage="Please enter your e-mail address." 42. Display="Dynamic"></asp:RequiredFieldValidator> 43. <asp:RegularExpressionValidator 44. ID="emailFormatValidator" runat="server" 45. ControlToValidate="emailTextBox" 46. ErrorMessage="Please enter an e-mail address in a 47. valid format." Display="Dynamic" 48. ValidationExpression= 49. "\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"> 50. </asp:RegularExpressionValidator> 51. </td> 52. </tr> 53. <tr> 54. <td style="width: 100px" valign="top">Phone number:</td> 55. <td style="width: 450px" valign="top"> 56. <asp:TextBox ID="phoneTextBox" runat="server"> 57. </asp:TextBox> 58. &nbsp;e.g., (555) 555-1234<br /> 59. <asp:RequiredFieldValidator ID="phoneInputValidator" 60. runat="server" ControlToValidate="phoneTextBox" 61. ErrorMessage="Please enter your phone number." 62. Display="Dynamic"></asp:RequiredFieldValidator> 63. <asp:RegularExpressionValidator 64. ID="phoneFormatValidator" runat="server" 65. ControlToValidate="phoneTextBox" 66. ErrorMessage="Please enter a phone number in a 67. valid format." Display="Dynamic" 68. ValidationExpression= 69. "((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"> 70. </asp:RegularExpressionValidator> 71. </td> 72. </tr> 73. </table> 74. <br /> 75. <asp:Button ID="submitButton" runat="server" Text="Submit" /> 76. <br /><br /> 77. <asp:Label ID="outputLabel" runat="server" 78. Text="Thank you for your submission." 79. Visible="False"></asp:Label> 80. </div> 81. </form> 82. </body> 83. </html> Examining Validation.aspx Validation.aspx uses a table to organize the page’s contents. Lines 24-25, 36-37 and 56-57 define TextBoxes for receiving the user’s name, e-mail address and phone number, respectively, and line 75 defines a Submit button. Lines 77-79 create a Label named outputLabel that displays the response from the server when the user successfully submits the form. Notice that that outLable’s Visible property is initially set to False, so that the Label does not appear in the client’s browser when the page loads for the first time. Using RequiredFieldValidator Control In this example, we use three RequiredFieldValidaor controls (found in the Validation section of the ToolBox) to ensure that the name, e-mail address and phone number Textboxes are not empty when the form is submitted. A RequiredFieldValidator makes an input control a required field. If such field an empty, validation fails. For example, lines 26-29 define RequiredFieldValidator nameInputValidator, which confirms that nameTextBox is not empty. Line 27 associates nameTextBox with nameInputValidator by setting the validator’s ControlToValidate property to nameTextBox. This indicates that nameInputValidator verifies the nameTextBox’s contents. Property ErrorMessage’s text (line 28) is displayed on the Web Form if the validation fails. If the user does not input any data in nameTextBox and attempts to submit the form, the ErrorMessage text is displayed in red. Because we set the control’s Display property to dynamic (line 29), the validator takes a space on the Web Form only when validation fails – space is allocated dynamically when validation fails, causing the controls below the validator to shift downwards to accommodate the ErrorMessage. Using RegularExpressionValidator Control The example also uses RegularExpressionValidator controls to match the e-mail address and phone number entered by the user against regular expressions. These controls determine whether the e-mail address and phone number were each entered in a valid format. For example, lines 43-50 create a RegularExpressionValidator named emailFormatValidator. Line 45 sets property ControlToValidate to emailTextBox to indicate that emailFormatValidator verifies the emailTextBox’s contents. A RegularExpressionValidator’s ValidationExpression property specifies the regular expression that validates the ControlToValidate’s contents. Clicking the ellipsis next to property ValidationExpression in the Properties window displays the Regular Expression Editor dialog, which contains a list of Standard expressions fot phone numbers, ZIP codes and other formatted information. Using RegularExpressionValidator Control You can also write your own custom expression. For the emailFormatValidator, we selected the standard expression Internet e-mail address, which uses the validation expression: \w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* This regular expression indicates that an e-mail address is valid if the part of the address before the @ symbol contains one or more word characters (alphanumeric characters or underscore), followed by zero or more strings comprised of a hyphen, plus sign, period or apostrophe and additional word characters. After the @ symbol, a valid e-mail address must contain one or more groups of word characters potentially separated by hyphens or periods, followed by a required period and another group of one more word characters potentially separated by hyphens or periods. For example, akhalil@aucegypt.edu, nathalie.khalil@hp.com, bob-white@myemail.com and bob’s-personal.email@white.email.com are all valid email addresses. If the user enters text in the emailTextBox that does not have the correct format and either clicks in a different text box or attempts to submit the form, the ErrorMessage text is displayed in red. Using RegularExpressionValidator Control We also use RegularExpressionValidator phoneFormatValidator (lines 6370) to ensure that the phoneTextBox contains a valid phone number before the form is submitted. In the Regular Expression Editor dialog, we select U.S. phone number, which assigns: ((\(d{3}\) ?) | (\d{3}-))?\d{3}-\d{4} to the ValidationExpression property. This expression indicates that a phone number can contain a three-digit area code either in parenthesis and followed by an optional space or without parenthesis and followed by required hyphen. After an optional area code, a phone number must contain three digits, a hyphen and another four digits. For example, (555) 123-4567, 555-123-4567 and 1234567 are all valid phone numbers. If all five validators are successful (i.e., each TextBox is filled in, and the email address and phone number provided are valid), clicking the Submit button sends the form’s data to the server. The server then responds by displaying the submitted data in the outputLabel (lines 77-79) Examining the Code-Behind File Validation.aspx.cs The code-behind file Validation.aspx.cs does not contain any implementation related to the validators. Web programmers using ASP.NET often design their Web pages so that the current page reloads when the user submits the form; this enables the program to receive input process it as necessary and display the results in the same page when it is loaded the second time. These pages usually contain a form that when submitted sends the values of all the controls to the server and causes the current page to be requested again. This event is known as a postback. Line 20 uses the IsPostBack property of class Page to determine whether the page is being loaded due to a postback. The first time that the Web page is requested, IsPostBack is false, and the page displays only the form for the user input. When the postback occurs (from the user clicking Submit), IsPostBack is true. Examining the Code-Behind File Validation.aspx.cs Lines 23-25 use the Request object to retrieve the values of nameTextBox, emailTextBox and phoneTextBox from the NameValueCollection Form. When the data is posted to the Web server, the XHTML form’s data is accessible to the Web application through the Request object’s Form array. Lines 28-34 append to outputLabel’s Text a line break, an additional message and an XHTML table containing the submitted data so that the user knows that the server received the data correctly. In a real business application, the data would be stored in a database or file at the this point in the application. Line 36 sets the outputLabel’s Visible property to true, so the user can see the thank you message and submitted data. Validation.aspx.cs 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. // Validation.aspx.cs // Code-behind file for the form demonstrating validation controls. using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. public partial class Validation : System.Web.UI.Page { // Page_Load event handler executes when the page is loaded protected void Page_Load( object sender, EventArgs e ) { // if this is not the first time the page is loading // (i.e., the user has already submitted form data) if ( IsPostBack ) { // retrieve the values submitted by the user string name = Request.Form[ "nameTextBox" ]; string email = Request.Form[ "emailTextBox" ]; string phone = Request.Form[ "phoneTextBox" ]; 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. // create a table indicating the submitted values outputLabel.Text += "<br />We received the following information:" + "<table style=\"background-color: yellow\">" + "<tr><td>Name: </td><td>" + name + "</td></tr>" + "<tr><td>E-mail address: </td><td>" + email + "</td></tr>" + "<tr><td>Phone number: </td><td>" + phone + "</td></tr>" + "<table>"; outputLabel.Visible = true; // display the output message } // end if } // end method Page_Load } // end class Validation Examining the Client-Side XHTML for a Web Form with Validation 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. The following is the XHTML and ECMAScript sent to the client browser when validation.aspx loads after the postback. <!– Validation.html <!– The XHTML and ECMAScript generated for Validation.aspx <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1"><title> Demonstrating Validation Controls </title></head> <body> <form name="form1" method="post" action="Validation.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="form1"> 12. <div> 13. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJODc5MTExMzA4D2QWAgIDD2QWAgITDw8WBB4EVGV4d AWZAlRoYW5rIHlvdSBmb3IgeW91ciBzdWJtaXNzaW9uLjxiciAvPldlIHJlY2Vpd mVkIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb246PHRhYmxlIHN0eWxlPSJi YWNrZ3JvdW5kLWNvbG9yOiB5ZWxsb3ciPjx0cj48dGQ+TmFtZTogPC90ZD48 dGQ+QXdhZCBLaGFsaWw8L3RkPjwvdHI+PHRyPjx0ZD5FLW1haWwgYWRk cmVzczogPC90ZD48dGQ+YWtoYWxpbEBhdWNlZ3lwdC5lZHU8L3RkPjwvdHI +PHRyPjx0ZD5QaG9uZSBudW1iZXI6IDwvdGQ+PHRkPjU1NS0xMjMtNDU2N zwvdGQ+PC90cj48dGFibGU+HgdWaXNpYmxlZ2RkZIgloue4R5DD4XjupTP6 O9AnPrG2" /> 23. </div> 24. 25. <script type="text/javascript"> 26. <!-27. var theForm = document.forms['form1']; 28. if (!theForm) { 29. theForm = document.form1; 30. } 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); } } // --> </script> <script src="/Validation/WebResource.axd?d=NaskQjO8lLGtm5y30YzEw2&amp;t=633518019041562500" type="text/javascript"></script> 43. 44. 45. <script src="/Validation/WebResource.axd?d=IzB9FRN0xVVSFPoDalUUKBsG9cfrTK5 P0v9k-eHhkAs1&amp;t=633518019041562500" type="text/javascript"></script> 46. <script type="text/javascript"> 47. <!-- 48. function WebForm_OnSubmit() { 49. if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false; 50. return true; 51. } 52. // --> 53. </script> 54. 55. <div> 56. Please fill out the following form.<br /> 57. <em>All fields are required and must 58. contain valid information.</em><br /> 59. <br /> 60. <table> 61. <tr> 62. <td style="width: 100px" valign="top">Name:</td> 63. <td style="width: 450px" valign="top"> 64. <input name="nameTextBox" type="text" value="Awad Khalil" id="nameTextBox" /><br /> 65. <span id="nameInputValidator" style="color:Red;display:none;">Please enter your name.</span> 66. </td> 67. </tr> 68. <tr> 69. <td style="width: 100px; height: 64px;" valign="top"> 70. E-mail address:</td> 71. <td style="width: 450px; height: 64px;" valign="top"> 72. <input name="emailTextBox" type="text" value="akhalil@aucegypt.edu" id="emailTextBox" /> 73. &nbsp;e.g., user@domain.com<br /> 74. <span id="emailInputValidator" style="color:Red;display:none;">Please enter your e-mail address.</span> 75. <span id="emailFormatValidator" style="color:Red;display:none;">Please enter an e-mail address in a 76. valid format.</span> 77. </td> 78. </tr> 79. <tr> 80. <td style="width: 100px" valign="top">Phone number:</td> 81. <td style="width: 450px" valign="top"> 82. <input name="phoneTextBox" type="text" value="555-123-4567" id="phoneTextBox" /> 83. &nbsp;e.g., (555) 555-1234<br /> 84. <span id="phoneInputValidator" style="color:Red;display:none;">Please enter your phone number.</span> 85. <span id="phoneFormatValidator" style="color:Red;display:none;">Please enter a phone number in a 86. valid format.</span> 87. </td> 88. </tr> 89. </table> 90. <br /> 91. <input type="submit" name="submitButton" value="Submit" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;submitButton&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))" id="submitButton" /> 92. <br /><br /> 93. <span id="outputLabel">Thank you for your submission.<br />We received the following information:<table style="background-color: yellow"><tr><td>Name: </td><td>Awad Khalil</td></tr><tr><td>E-mail address: </td><td>akhalil@aucegypt.edu</td></tr><tr><td>Phone number: </td><td>555-123-4567</td></tr><table></span> 95. <script type="text/javascript"> 96. <!-97. var Page_Validators = new Array(document.getElementById("nameInputValidator"), document.getElementById("emailInputValidator"), document.getElementById("emailFormatValidator"), document.getElementById("phoneInputValidator"), document.getElementById("phoneFormatValidator")); 98. // --> 99. </script> 100. 101.<script type="text/javascript"> 102.<!-103.var nameInputValidator = document.all ? document.all["nameInputValidator"] : document.getElementById("nameInputValidator"); 104.nameInputValidator.controltovalidate = "nameTextBox"; 105.nameInputValidator.errormessage = "Please enter your name."; 106.nameInputValidator.display = "Dynamic"; 107.nameInputValidator.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; 108.nameInputValidator.initialvalue = ""; 109.var emailInputValidator = document.all ? document.all["emailInputValidator"] : document.getElementById("emailInputValidator"); 110.emailInputValidator.controltovalidate = "emailTextBox"; 111.emailInputValidator.errormessage = "Please enter your e-mail address."; 112.emailInputValidator.display = "Dynamic"; 113.emailInputValidator.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; 114.emailInputValidator.initialvalue = ""; 115.var emailFormatValidator = document.all ? document.all["emailFormatValidator"] : document.getElementById("emailFormatValidator"); 116.emailFormatValidator.controltovalidate = "emailTextBox"; 117.emailFormatValidator.errormessage = "Please enter an e-mail address in a \r\n valid format."; 118.emailFormatValidator.display = "Dynamic"; 119.emailFormatValidator.evaluationfunction = "RegularExpressionValidatorEvaluateIsValid"; 120.emailFormatValidator.validationexpression = "\\w+([-+.\']\\w+)*@\\w+([.]\\w+)*\\.\\w+([-.]\\w+)*"; 121.var phoneInputValidator = document.all ? document.all["phoneInputValidator"] : document.getElementById("phoneInputValidator"); 122.phoneInputValidator.controltovalidate = "phoneTextBox"; 123.phoneInputValidator.errormessage = "Please enter your phone number."; 124.phoneInputValidator.display = "Dynamic"; 125.phoneInputValidator.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; 126.phoneInputValidator.initialvalue = ""; 127.var phoneFormatValidator = document.all ? document.all["phoneFormatValidator"] : document.getElementById("phoneFormatValidator"); 128.phoneFormatValidator.controltovalidate = "phoneTextBox"; 129.phoneFormatValidator.errormessage = "Please enter a phone number in a \r\n valid format."; 130.phoneFormatValidator.display = "Dynamic"; 131.phoneFormatValidator.evaluationfunction = "RegularExpressionValidatorEvaluateIsValid"; 132.phoneFormatValidator.validationexpression = "((\\(\\d{3}\\) ?)|(\\d{3}-))?\\d{3}\\d{4}"; 133.// --> 134.</script> 135. 136.<div> 137. 138.<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBQLg+/rDAQKLsYSOBwKCkfPgDAKE8IO1CQKSuuDUC1MYAZi vg5d2BTuuFNpOO42pevwV" /> 139.</div> 140. 141.<script type="text/javascript"> 142.<!-143.var Page_ValidationActive = false; 144.if (typeof(ValidatorOnLoad) == "function") { 145.ValidatorOnLoad(); 146.} 147. 148.function ValidatorOnSubmit() { 149.if (Page_ValidationActive) { 150.return ValidatorCommonOnSubmit(); 151.} 152.else { 153.return true; 154.} 155.} 156.// --> 157.</script> 158.</form> 159.</body> 160.</html>