Walkthrough: Validating User Input in a Web Forms Page
This walkthrough illustrates how to use ASP.NET validator controls to check user input in a Web page. You will work with some controls that perform all checking automatically, requiring no code. You will also create a custom validator with code that you write, which illustrates how you can add your own logic to the validation framework in the page. Finally, you will learn how you can validate user input conditionally, depending on choices that the user makes in a page.
In the walkthrough, you will create a page for a Web site that allows visitors to request a reservation. Because the purpose of the walkthrough is to illustrate validation, the nature of the reservation is not important for this walkthrough (for example, if could be for a restaurant, a community center meeting room, or something else), and the page does not actually process the reservation.
The page you create will prompt the user for an e-mail address, the number of people to reserve for, and a preferred date. The page also allows the user to request a telephone confirmation of the reservation. (The default for this page, if implemented, would be e-mail confirmation.)
Security Note: |
---|
By default, the Web Forms page automatically validates that malicious users are not attempting to send script to your application. For more information, see Script Exploits Overview. |
During this walkthrough, you will learn how to:
Use validator controls to check user input in an ASP.NET Web page.
Format the display of validation error messages.
Create custom validation by writing code.
Prerequisites
In order to complete this walkthrough, you will need:
- Visual Studio and the .NET Framework.
Creating the Web Site and Page
In the first part of the walkthrough, you will create a Web site and a page where you can work with styles.
If you have already created a Web site in Visual Studio (for example, by working with the topic Walkthrough: Creating a Basic Web Page in Visual Web Developer ), you can use that Web site and skip to "Adding Controls" later in this walkthrough. Otherwise, create a new Web site and page using the following steps.
To create a file system Web site
Open Visual Studio.
On the File menu, click NewWeb Site.
The New Web Site dialog box appears.
In the Language list, click the programming language you prefer to work in.
The programming language you choose will be the default for your Web site, but you can set the programming languages for each page individually.
Under Visual Studio installed templates, click ASP.NET Web Site.
In the Location box, enter the name of the folder where you want to keep the pages of your Web site.
For example, type the folder name C:\WebSites.
Click OK.
Visual Studio creates the folder and a new page named Default.aspx.
Adding Controls
You will use only a few controls to prompt the user the information required for the reservation.
To add controls and text
Switch to Design view.
Type a page heading such as Submit a Reservation.
From Standard group of the Toolbox, drag the following controls onto the page and set their properties as indicated.
Control
Properties
ID: textEmail
ID: textNumberInParty
ID: textPreferredDate
ID: buttonSubmit
Text: Submit Request
ValidationGroup: AllValidators
ID: labelMessage
Text: (blank)
Note
The exact layout of the page is not important.
Type text in front of the text boxes as captions.
Double-click the Submit Request button to create a handler for its Click event and then add the following highlighted code:
Protected Sub buttonSubmit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) If Page.IsValid Then labelMessage.Text = "Your reservation has been processed." End If End Sub
protected void buttonSubmit_Click(object sender, EventArgs e) { if (Page.IsValid) { labelMessage.Text = "Your reservation has been processed."; } }
The button handler simply displays a message; it performs no actual processing. However, the message display will allow you to test the effect of validation later in the walkthrough.
Switch to Design view, double-click a blank area in the page to create a Page_Load handler, and then add the following highlighted code:
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As EventArgs) labelMessage.Text = "" End Sub
protected void Page_Load(object sender, EventArgs e) { labelMessage.Text = ""; }
This code clears the message displayed by the page when all validation passes. The code helps with testing later in the walkthrough.
Adding Basic Validation
For your imaginary reservation system, you will want to enforce the following validation checks:
The e-mail address is required, and it must be formatted properly; for example, someone@example.com. (It is generally not practical to check that an e-mail address is someone's real address; however, you can check that the address conforms to the proper pattern for e-mail addresses.)
The number of people is also required, and it must be numeric.
The preferred date is required.
You can add all of this validation using validator controls, which perform all of the checks for you and automatically display errors.
Note
Later in the walkthrough you will add another check to be sure that users enter a valid date.
To add basic validation
Switch to Design view. From the Validation group of the Toolbox, drag a RequiredFieldValidator control and drop it next to the textEmail text box.
Set the following properties of the RequiredFieldValidator control:
Property
Setting
textEmail
Binds the validator control to the text box whose contents you want to validate.
Dynamic
Specifies that the control renders (and takes up space in the page) only if required in order to display an error.
E-mail address is required.
Displays text in a summary error, which you will configure later in the walkthrough.
*
A star is a conventional way of indicating that a field is required. This text will be displayed only if there is an error.
AllValidators
As with radio buttons, you can group validators into groups that are treated as a unit. You will learn more about grouping validators later in the walkthrough.
What you have done is added a test to be sure the user enters an e-mail address. The validator control performs all the checking and error display with requiring you to add code to the page.
From the Validation group of the Toolbox, drag a RegularExpressionValidator control and drop it next to the RequiredFieldValidator you just added.
Set the following properties of the RegularExpressionValidator control:
Property
Setting
textEmail
You are again validating the user's entry in the e-mail box.
Dynamic
E-mail addresses must be in the format of name@domain.xyz.
A longer error message.
Invalid format!
A short error message.
AllValidators
As with radio buttons, you can group validators into groups that are treated as a unit. You will learn more about grouping validators later in the walkthrough.
With the RegularExpressionValidator control still selected, in the Property window click the ellipsis button in the ValidationExpression box.
Regular expressions constitute a language that can be used to find precisely defined patterns in strings. In the RegularExpressionValidator control, you define a regular expression for the pattern that is valid — in this case, the pattern for a valid e-mail address.
The Regular Expression Editor contains a list of commonly used regular expressions so that you can use the validator control without learning regular expression syntax.
In the Standard Expressions list, click Internet E-mail Address.
The regular expression for an e-mail address is put in the Validation Expression box.
Click OK to close the dialog box.
Add another RequiredFieldValidator control, using the instructions from Steps 1-3. This time, however, bind it to the textNumberInParty text box and set its ErrorMessage property to Please indicate how many people are in your party.
From the Validation group of the Toolbox, drag a RangeValidator control and drop it next to the RequiredFieldValidator you just added.
Set the following properties of the RangeValidator control:
Property
Setting
textNumberInParty
Dynamic
Enter a number between 1 and 20 for the number of people in your party.
20
In this case, an arbitrary but high value.
1
In this application, a reservation requires at least one person.
Enter a number between 1 and 20.
Integer
AllValidators
The RangeValidator control performs two functions: it ensures that the data a user enters is numeric, and it checks that the number is between the specified minimum and maximum values.
Testing the Page
You can now test the validator controls that you have so far.
To test basic validation
Press CTRL+F5 to run the page.
When the page appears in the browser, click the Submit Request button.
Several validation errors are displayed, because you have not filled in some required fields. Note that the validation errors are displayed immediately — the page is not submitted. By default, the validator controls inject client-side ECMAScript (JavaScript) into the page to perform validation checking in the browser. This gives users instant feedback on validation errors; without the client script, checking for validation errors would require a round trip to the server, which could be slow at times. In fact, you cannot submit the page until the client-side validation checks all pass. (The same validation check is performed again when the page is submitted as a security precaution.)
Check the validation on the textEmail text box by typing an invalid e-mail address, and then again with a valid e-mail address such as your own.
Check that you can enter only numeric values between 1 and 20 in the Number of people in party text box.
When you have entered valid values, click the Submit Request button. If the validation passes for all controls, you will see the message Your reservation has been processed.
After you have confirmed that validation is working as expected, close the browser.
If validation is not working as expected, double-check that you have made all the property settings listed above and then run the page again.
Alternative Ways to Display Error Information
By default, validator controls display error text in-place; that is, they display the value of the control's Text property at the control's location in the page. At times you might want to display error information in different ways. The ASP.NET validator controls provide you with these additional options:
Summarize all validation errors in one place. You can do this in addition to or instead of showing in-place errors. Displaying error summaries also allows you to display longer error messages.
Display a pop-up message in the browser with error information. This option works only on script-enabled browsers.
You can add both of these display options using the ValidationSummary control. In this part of the walkthrough, you'll add both display features to the page.
To display validation information in alternative ways
From the Validation group of the Toolbox, drag a ValidationSummary control onto the page.
Set the ValidationSummary control's ValidationGroup property to AllValidators.
Run the page.
Perform the same testing you did earlier in the walkthrough.
For each error, you see error information in two places. A short error message (the validator's Text property value) is displayed where the validator control is. The longer error message (the control's ErrorMessage property value) is displayed in the ValidationSummary control.
Close the browser.
Set the ValidationSummary control's ShowMessageBox property to true.
Run the page.
Perform the same tests.
This time, each error results in a pop-up message in the browser.
Close the browser.
Adding Custom Validation to Check Date Entry
The ASP.NET validation controls do not include a control that automatically checks for a valid date. However, you can use the CustomValidator control for that purpose. The custom validator allows you to write your own validation code to check for any condition your application requires. In this walkthrough, you will use the CustomValidator to check that the value the user enters into the textPreferredDate text box can be converted to a date value.
You will add two blocks of custom validation code. The first is the custom validation code that runs when the page is submitted. You must always have server-side validation logic for a CustomValidator control. You will also write some client script (ECMAScript or JavaScript) that performs a similar check in the browser, so that the user can have immediate feedback.
To use a CustomValidator control to check for a valid date
From the Validation group of the Toolbox, drag a CustomValidator control onto the page and position it next to the textPreferredDate text box.
Set the following properties of the CustomValidator control:
Property
Setting
textPreferredDate
Dynamic
Enter a date in the format m/d/yyyy.
Invalid date format (requires m/d/yyyy).
AllValidators
Double-click the CustomValidator control to create a handler for its ServerValidate event and then add the following highlighted code:
Protected Sub CustomValidator1_ServerValidate( _ ByVal source As Object, _ ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Try DateTime.ParseExact(args.Value, "m/d/yyyy", _ System.Globalization.DateTimeFormatInfo.InvariantInfo) args.IsValid = True Catch args.IsValid = False End Try End Sub
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args) { try { DateTime.ParseExact(args.Value, "m/d/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo); args.IsValid = true; } catch { args.IsValid = false; } }
This code runs when the user submits the page. The code interacts with the validator control using the ServerValidateEventArgs (args) object passed into the handler. The value that the user has entered into the textPreferredDate text box is passed as the args object's Value property. After you have checked whether the user's entry is valid, you set the args object's IsValid property to true or false. If you set it to false, the validator will display its error message.
In this example, the code uses a try-catch block to determine whether the user's entry can be converted into a DateTime object. If the user enters an invalid value (anything that does not conform to a date in the format m/d/yyyy), the DateTime object's ParseExact method throws an exception, and the Catch block is executed.
Note
The value of the provider parameter of the DateTime.ParseExact method is culture independent. If you need to use the current culture, you can set provider to null.
In the Button_Click handler, add the following highlighted code:
Protected Sub buttonSubmit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) If Page.IsValid Then labelMessage.Text = "Your reservation has been processed." Else labelMessage.Text = "Page is not valid." End If End Sub
protected void buttonSubmit_Click(object sender, EventArgs e) { if(Page.IsValid) { labelMessage.Text = "Your reservation has been processed."; } else { labelMessage.Text = "Page is not valid."; } }
When you use a CustomValidator control, you must check the Page.IsValidproperty in any server-side processing to be sure that all the validation checks have passed. The IsValid property returns the cumulative state of all the validator controls on the page. This property is used to make sure that all validation checks have passed any server-side processing.
You have now added the server-side code for the CustomValidator control to check for a valid date. As you know from earlier in the walkthrough, validator controls also check a user's entry using client script. You can add client script to the CustomValidator control as well. In effect, you write client script that duplicates the logic that your server-side validation performs. Writing client-side custom validation code is not always practical (for example, if the custom code validates a user's entry by looking in a server-side database). However, in this case you can create client-side code that performs essentially the same check that your server-side code is performing.
To add client script to the CustomValidator control
Open or switch to Default.aspx.
In the <head> element of the page, add the following client script block:
<script language="javascript"> function validateDate(oSrc, args) { var iDay, iMonth, iYear; var arrValues; arrValues = args.Value.split("/"); iMonth = arrValues[0]; iDay = arrValues[1]; iYear = arrValues[2]; var testDate = new Date(iYear, iMonth - 1, iDay); if ((testDate.getDate() != iDay) || (testDate.getMonth() != iMonth - 1) || (testDate.getFullYear() != iYear)) { args.IsValid = false; return; } return true; }</script>
Note
ECMAScript (JavaScript) is case-sensitive; enter the code exactly as you see it here.
This code is similar to the server-side validation check, but not as strict. The user's entry is passed into the function as the args object's Value property, and you can set the object's IsValid property to indicate whether the value passes validation. In this example, the code checks to make sure valid numeric dates were entered.
Note that the code for the custom validation is slightly different in client script than it is in server code. ECMAScript does not provide exactly the same functionality as that in the .NET Framework. Therefore, the ECMAScript parses the entered text instead of the ParseExact code that you use on the server to check the date. However, the two validation checks (client and server) are similar enough to provide the functionality you need.
Put the insertion point in the <asp:customvalidator> element to select it.
In the Properties window, set the control's ClientValidationFunction property to validateDate, which is the name of the ECMAScript function that you just created.
You have now added a custom validation check that works both in client script to check the user's entry immediately and then again when the page is submitted to the server.
Testing Custom Validation
You can now test that your custom validation is working properly.
To test custom validation
Temporarily disable the client-side validation by setting the EnableClientScript property of the CustomValidator control to false.
Press CTRL+F5 to run the page.
Fill in an e-mail address and the number of people in the party so that the validation for those fields passes.
In the date text box, enter a string that is obviously not a date and then click the Submit Request button.
Your page performs a round trip to the Web server, where the server-side validation fails. The test for IsValid fails and labelMessage says "Page is not valid."
Fill in a valid date value (such as 11/17/2005) and click the button.
This time, the date value passes validation, so you see the confirmation message created in the button's Click handler.
Close the browser.
Re-enable client-side validation by setting the EnableClientScript property of the CustomValidator control back to true.
Run the page again and enter valid values for the e-mail address and number of people in the party.
Enter an invalid date value into the date text box and then press the TAB key. (Do not click the button.)
As soon as the date text box loses focus, the client-side validation script runs and you see an error message.
Note
If you are using the auto-complete option in Internet Explorer, selecting a value from the auto-complete list will fill a value into the text box, but the client-side validator will not run.
Click the Submit Request button.
Because the client-side validation for the date text box has failed, the page is not submitted.
Correct the date value and press the TAB key again.
The error message disappears. You can now submit the form.
Adding Optional Controls with Conditional Validation
In the final part of the walkthrough, you will add some optional information to the reservation form. Users can check a box to indicate that they want telephone confirmation of their reservation. If they do, they must enter their telephone number. The page will therefore contain two additional controls: a check box and a text box.
As before, you will use validation to check the user's entries. You will use a RequiredFieldValidator control to be sure that users enter a phone number, and a RegularExpressionValidator control to check its format. The telephone number is optional; you need to check the phone number only if the user has selected the Confirm reservation by phone check box. You therefore will write some simple code that turns validation on or off for the telephone number depending on the state of the check box.
To add conditional validation
From the Standard group of the Toolbox, drag a CheckBox control onto the page and set the following properties:
Property
Setting
checkPhoneConfirmation
True
When the user clicks the check box, the page will perform a round trip and conditionally enable the text box and the validation for it.
False
Clicking the CheckBox will not automatically cause validation.
Confirm reservation by telephone.
Drag a TextBox control onto the page underneath the CheckBox control and set the following properties:
Property
Settings
textPhoneNumber
False
The text box will not be enabled until the user clicks the check box.
Type text such as Telephone number: next to the phone number text box as a caption.
From the Validation group of the Toolbox, drag a RequiredFieldValidator onto the page and set the following properties:
Property
Setting
validatorRequiredPhoneNumber
You did not set the ID of validator controls earlier in the walkthrough, but in this case you will be referring to the validator control in code, so you it is helpful to give it a mnemonic ID.
textPhoneNumber
Dynamic
You must provide a phone number.
*
(Leave blank)
If this property is blank, the validator does not belong to the AllValidators group that you established for the other validator controls on the page. As a consequence, by default this validator is not checked when the buttonSubmit control is clicked.
Drag a RegularExpressionValidator control onto the page and set the following properties:
Property
Setting
validatorRegExPhoneNumber
textPhoneNumber
Dynamic
Phone number format is invalid
Invalid format
(Use the Regular Expression Editor dialog box to select U.S. Phone Number or another phone number expression.)
(Leave blank)
Double-click the checkPhoneConfirmation control to create a handler for its CheckedChanged event and then add the following highlighted code:
Protected Sub checkPhoneConfirmation_CheckedChanged( _ ByVal sender As Object, _ ByVal e As System.EventArgs) If checkPhoneConfirmation.Checked = True Then textPhoneNumber.Enabled = True validatorRequiredPhoneNumber.ValidationGroup = "AllValidators" validatorRegExPhoneNumber.ValidationGroup = "AllValidators" Else textPhoneNumber.Enabled = False validatorRequiredPhoneNumber.ValidationGroup = "" validatorRegExPhoneNumber.ValidationGroup = "" End If End Sub
protected void checkPhoneConfirmation_CheckedChanged( object sender, EventArgs e) { if(checkPhoneConfirmation.Checked) { textPhoneNumber.Enabled = true; validatorRequiredPhoneNumber.ValidationGroup = "AllValidators"; validatorRegExPhoneNumber.ValidationGroup = "AllValidators"; } else { textPhoneNumber.Enabled = false; validatorRequiredPhoneNumber.ValidationGroup = ""; validatorRegExPhoneNumber.ValidationGroup = ""; } }
When the user clicks the check box, the two validators associated with the text box are added to the validation group that the other validator controls belong to. The effect is that all the validators on the page, including those for the phone number, will be checked when the user submits the page. If the user clears the check box, the validators are removed from the group and are therefore not processed when the Submit Request button is clicked.
Testing Conditional Validation
You can now test that conditional validation is working properly.
To test conditional validation
Press CTRL+F5 to run the page.
Enter valid information for the e-mail address, number of people in the party, and date.
Click Submit Request.
The page is submitted and you see the confirmation message.
Select the Confirm reservation by phone check box.
Click Submit Request again.
This time, you see an error message (a star next to the phone text box). When you clicked the check box, you enabled validation for the text box.
Enter an invalid phone number and then click Submit Request again to confirm that the text box will not accept an invalid phone number.
Enter a correctly formatted phone number and click the submit button to confirm that the validator control accepts well-formed data.
Note
If you have selected U.S. Phone Number in the Regular Expression Editor for the ValidationExpression property of the RegularExpressionValidator control, a correctly formatted phone number consists of the area code (optional field with 3 numeric characters, enclosed in parentheses or followed by a dash), followed by a set of 3 numeric characters, a dash and then a set of 4 numeric characters. Valid examples are (425) 555-0123, 425-555-0123 or 555-0123.
Next Steps
The validation you added to the Web Forms page illustrates the basic concepts of Web validation controls.
An important aspect of validation is understanding how it helps you increase the security for your Web site. For details, see Overview of Web Application Security Threats