Chapter 9 – Validating User Input Dr. Stephanos Mavromoustakos Chapter Overview To prevent your system from receiving invalid data, it’s important to validate this data before you allow your system to work with it. This chapter will cover: What is user input and why is it important to validate it? What does ASP.NET 3.5 have to offer to aid you in validating user input? How do you work with the built-in validation controls and how do you create solutions that are not supported with the standard tools? How do you send e-mail using ASP.NET? How do you read text files? Getting Data from the User The input from the user can be sent to the web server with two different techniques, GET and POST. The GET data is appended to the actual address of the page being requested whereas with the POST method the data is sent in the body of the request for the page (chapter 4). With the GET method, data is added to the query string of a page. You can retrieve it using the QueryString property of the Request object (chapter 7). Imagine you are requesting the page: http://www.planetWrox.com/Reviews/ViewDetails.a spx?id=34&catId=3 The query string is id=34&catId=3. The question mark is used to separate the query string from the rest of the address. To access individual items in the query string, you can use the Get method of the QueryString collection (see below): Getting Data from the User Dim id As Integer = Convert.ToInt32(Request.QueryString.Get(“id”)) `id is now 34 Dim catId As Integer = Convert.ToInt32(Request.QueryString.Get(“catId ”)) `id is now 3 The POST method on the other hand gets its data from a form with controls that have been submitted to the server. Imagine you have a form with two controls: a TextBox called txtAge to hold the user’s age and a Button to submit that age to the server. In the Button control’s Click event you could write the following code to convert the user’s input to an integer: Dim age As Integer = Convert.ToInt32(txtAge.Text) `age now holds the user’s age Validating User Input in Web Forms Never Trust User Input ASP.NET 3.5 comes with six useful validation controls. Five of them are used to perform the actual validation whereas the final control – the ValidationSummary – is used to provide feedback to the user about any errors made in the page. The validation controls can be easily hooked to other controls like the TextBox or a DropDownList; however, they also support custom validation controls A Warning on Client-Side Validation Never rely on client-side validation to prevent users from sending invalid data to your system. It’s easy to disable JavaScript in the browser, rendering the clientside validation useless. In addition, a malicious user can easily bypass the entire page in the browser and send information directly to the server, which will happily accept and process it. Server-side validation, is the only real means of validation. It’s effectively the only way to prevent invalid data from entering your system Practice- Using the RequiredFieldValidator In this exercise, you will create a user control called ContactForm.ascx. It can be placed in a web page so visitors to your site can leave some feedback. In later exercises you will extend the control by sending the response by e-mail to your e-mail account. Open your project and add a new user control in the Controls folder. Call it ContactForm.ascx. Make sure it uses a Code Behind file. Switch to Design View and insert a table by choosing TableInsert Table. Create a table with eight rows and three columns. Practice- Using the RequiredFieldValidator Merge the three cells of the first row. To do this, select all three cells, right-click the selection, and choose ModifyMerge Cells In the merged cell, type some text such as “Get in touch with us” In the first cell of the second row type the text Your name. Into the second cell of the same row, drag a textbox and call it txtName. Into the last cell of the second row, drag a RequiredFieldValidator from the Validation category. Finally into the second cell of the last row, drag a Button. Rename the button to btnButton by setting its ID, and set its Text property to Send. Practice- Using the RequiredFieldValidator Practice- Using the RequiredFieldValidator Click the RequiredFieldValidator once in the Design View and then open up its properties. Set the following properties on the control: Property Value ErrorMessage Please enter your name Text * ControlToValidate txtName Save the changes and close the control Open Contact.aspx from the About folder and switch to Design View. Practice- Using the RequiredFieldValidator From the Solution Explorer, drag the ContactForm.ascx into the main content area of the page. Switch back to Markup View, and you see this control declaration: <uc1:ContactForm ID="ContactForm1" runat="server" /> Save the page and then press Ctrl+F5 to open it in your browser. Leave the Name text box empty and click the Send button. Note that the page is not submitted to the server. Instead, you should see a red asterisk appear in the row for the name field to indicate an error Enter your name and click Send again. The page now successfully posts back to the server Practice- Using the RequiredFieldValidator The Standard Validation Controls Four of the five validation controls operate in the same way. The last control, the CustomValidator allows you write custom functionality that is not supported out of the box. The RangeValidator control enables you to check whether a value falls within a certain range. The control is able to check data types like strings, numbers, dates, and currencies. The RegularExpressionValidator control allows you to check a value against a regular expression. Regular expressions offer a compact syntax that allows you to search for patterns in text strings. Regular expressions are complex, but VWD comes with a few build-in expressions that make it easy to validate values like e-mail addresses and zip codes. The CompareValidator can be used to compare the value of one control to another value. This is often used in sign-up forms where a user has to enter a password twice to make sure they type the same password both times. Also, you can compare it against a constant value. Practice – Extending the Contact Form In this exercise, you extend the Contact form and add fields for an e-mail address, a home phone number, and a business phone number. You will use the validation controls to ensure the e-mail address is in valid format, and that at least one of the two phone numbers is filled in. To make sure users enter a correct e-mail address, they are asked to enter it twice. If you don’t like this behavior, you can simply delete the row with the text box for the second e-mail address and ignore the CompareValidator. Practice – Extending the Contact Form Open ContactForm.ascx from the Controls folder again and switch it to Design View In the second column, drag five additional text boxes in the empty table cells between the textbox for the name and the Send button. From top to bottom, name the controls as follows 1. txtEmailAddress 2. txtEmailAddressConfirm 3. txtPhoneHome 4. txtPhoneBusiness 5. txtComments Set the TextMode property of txtComments to MultiLine and then make the control a little wider and taller in the designer so it’s easier for a user to add a comment. You can also adjust the table’s column width to align the error message closer to the text box controls In the first cell of the rows to which you added the TextBox controls, add the text as shown below: Practice – Extending the Contact Form In the last column of the row for the first email address, drag a RequiredFieldValidator and a RegularExpressionValidator. In the last column of the row for the second email address, drag a RequiredFieldValidator and a CompareValidator. Finally, in the last cell for the comments row, drag a RegularFieldValidator. For each of the validation controls, set the Text property to an asterisk (*) and the Display property to Dynamic. Then set the remaining properties for the controls as shown in the following table: Practice – Extending the Contact Form Practice – Extending the Contact Form Control Properties you need to set RequiredFieldValidator (for the first email address) ErrorMessage: Please enter an email address txtEmailAddress ControlToValidate: RegularExpressionValidator ErrorMessage: Please enter a valid email address txtEmailAddress ControlToValidate: RequiredFieldValidator ErrorMessage: (for the second email address) ControlToValidate: Please Confirm the email address txtEmailAddressConfirm CompareValidator ErrorMessage: ControlToValidate: ControlToCompare: Please retype the email address txtEmailAddressConfirm txtEmailAddress RequiredFieldValidator (for the Comments field) ErrorMessage: ControlToValidate: Please enter a comment txtComments Practice – Extending the Contact Form Still in the Design View, click the RegularExpressionValidator once and locate its ValidationExpression property. When you click the property in the grid, the grid shows a button with ellipses. When you click that button you get a dialog box that allows you to select a regular expression. Click Internet email address from the list. Click OK to add the property to the control Practice – Extending the Contact Form Save all changes and close your browsers. Then request Contact.aspx in the browser. Play around with the various validators and see how they work The CustomValidator and ValidationSummary Controls The CustomValidator allows you to write custom validation functions for both the client (in JavasScript) and the server. This gives you great flexibility with regards to the data you want to validate. The ValidationSummary provides the user with a list of errors that it retrieves from the ErrorMessage properties. It can display these errors in three different ways: using a list embedded in the page, using a JavasScript alert box, or using both at the same time. You control this with the ShowMessageBox and ShowSummary properties. Additionally, the DisplayMode property enables you to change the way the list of errors is presented. The default setting is BulletedList where each error is an item in a bulleted list, but other options are List (without bullets) and SingleParagraph Practice – Sending E-mail Messages Under the Demos folder create a new file called Email.aspx. Make sure it’s based on your own base page template. Change the page’s Title to E-mail Demo Switch to the Code Behind by pressing F7 and at the top of the file, before the class definition, add the following statement: Imports System.Net.Mail Add the following code to a Page_Load handler (add your email info): Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim myMessage As MailMessage = New MailMessage() myMessage.Subject = "Test Message" myMessage.Body = "Hello World" myMessage.From = New MailAddress(“you@yourprovider.com", "Sender Name") myMessage.To.Add(New MailAddress(" you@yourprovider.com ", “Received Name")) Dim mySmtpClient As SmtpClient = New SmtpClient() mySmtpClient.Send(myMessage) End Sub Practice – Sending E-mail Messages Open web.config and scroll all the way down. Right before the closing </configuration> tag, add the following: <system.net> <mailSettings> <smtp deliveryMethod="Network" from=“Your Name &lt;you@yourprovider.com&gt;"> <network host=“smtp.yourprovider.com" /> </smtp> </mailSettings> </system.net> Don’t forget to use your own name, email address and smtp. Cyta’s is mailout.cytanet.com.cy Save all changes and then request the page Email.aspx in your browser. After a while you should receive an email message at the address you specified The CustomValidator and ValidationSummary Controls The CustomValidator allows you to write custom validation functions for both the client (in JavaScript) and the server (using VB.NET or C≠). The ValidationSummary provides the user with a list of errors that it retrieves from the individual validation control’s ErrorMessage properties. It can display these errors in three different ways: using a list embedded in the page, using a JavaScript alert box, or using both at the same time. You control this setting with the ShowMessageBox and ShowSummary properties. Additionally, the DisplayMode property enables you to change the way the list of errors is presented Practice – Writing Client- and Server-Side Validation Methods In this exercise, you use the CustomValidator to ensure at least one of the two phone numbers is entered. The validation is carried out at the client and at the server. Additionally, you see how to use the ValidationSummary control to provide feedback to the user Go back to the ContactForm.ascx and switch it to Design View. Right-click the row with the Button control in it and choose InsertRow Below from the context menu Select the three cells of the row, right-click them, and choose ModifyMerge Cells From the Validation category, drag a ValidationSummary control into this cell In the empty cell after the text box for the Home phone number, drag a CustomValidator control and set the following properties: Practice – Writing Client- and Server-Side Validation Methods Property Value Display Dynamic ErrorMessage Please enter your home or business phone number Text * ClientValidationFunction ValidatePhoneNumbers Still on the Properties Grid for the CustomValidator control, click the button with the lightning bolt to switch to Events mode. Double-click the event ServerValidate to have VWD write an event handler for you. Add the following code: Practice – Writing Client- and Server-Side Validation Methods Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventA rgs) Handles CustomValidator1.ServerValidate If txtPhoneHome.Text IsNot String.Empty Or txtPhoneBusiness.Text IsNot String.Empty Then args.IsValid = True Else args.IsValid = False End If End Sub Practice – Writing Client- and Server-Side Validation Methods Switch to Markup View of the user control and add the following block of JavaScript code on top right before the table with the controls: <script type="text/javascript"> function ValidatePhoneNumbers(source, args) { var txtPhoneHome = document.getElementById('<%= txtPhoneHome.ClientID %>'); var txtPhoneBusiness = document.getElementById('<%= txtPhoneBusiness.ClientID %>'); if (txtPhoneHome.value != '' || txtPhoneBusiness.value != '') { args.IsValid = true; } else { args.IsValid = false; } } </script> Practice – Writing Client- and Server-Side Validation Methods Save all your changes and then request the page Contact.aspx in your browser. Note that you can’t submit the form if you haven’t at least entered one of the two phone numbers. Also the ValidationSummary shows a list of all the problems with the data entered in the form. Practice – Writing Client- and Server-Side Validation Methods Practice – Writing Client- and Server-Side Validation Methods Go back to VWD and click the ValidationSummary control in Design View. On the Properties Grid, change ShowMessageBox to True and ShowSummary to False. Also, set its HeaderText property to: Please correct the following errors before you press the Send button. Open the page in the browser again and click the Send button once more. Note that you now get a client-side alert Practice – Sending mail from the ContactForm User Control This exercise shows you how to use email to send the user data from the contact form to your own inbox. As the body of the email message, the code reads in a text file that contains placeholders. These placeholders are filled with the actual user data from the form and then sent by email. Right-click the App_Data folder and choose Add New Item. Name the text file ContactForm.txt Enter the following text in the text file: Hi there, A user has left the following feedback at the site: Name: Email address: Home Phone: Business Phone: Comments: ≠≠Name≠≠ ≠≠Email≠≠ ≠≠HomePhone≠≠ ≠≠BusinessPhone≠≠ ≠≠Comments≠≠ Practice – Sending mail from the ContactForm User Control Open the Code Behind of the ContactForm.ascx user control and import the following namespace at the top of the file before the class definition. Imports System.Net.Mail Switch to Markup View and add runat=“server” and id=“FormTable” attributes to the table element. This way you can hide the entire table when the form has been submitted. <table class="style1" runat="server" id="FormTable"> Scroll down to the end of the file and right after the closing </table> tag, add a label called lblMessage. Set its Text property to Message Sent. Hide the label by setting the Visible property to False <asp:Label ID="lblMessage" runat="server" Text="Message Sent" Visible="false"></asp:Label> Switch into Design View and then set ShowSummary of the ValidationSummary back to True and ShowMessageBox to False. Next, double-click the Send button. Inside the event handler add this code: Practice – Sending mail from the ContactForm User Control If Page.IsValid Then Dim fileName As String = Server.MapPath("~/App_Data/ContactForm.txt") Dim mailBody As String = System.IO.File.ReadAllText(fileName) mailBody = mailBody.Replace("≠≠Name≠≠", txtName.Text) mailBody = mailBody.Replace("≠≠Email≠≠", txtEmailAddress.Text) mailBody = mailBody.Replace("≠≠HomePhone≠≠", txtPhoneHome.Text) mailBody = mailBody.Replace("≠≠BusinessPhone≠≠", txtPhoneBusiness.Text) mailBody = mailBody.Replace("≠≠Comments≠≠", txtComments.Text) Dim myMessage As MailMessage = New MailMessage() myMessage.Subject = "Response from web site" myMessage.Body = mailBody myMessage.From = New MailAddress(“you@yourprovider.com", “Bob") myMessage.To.Add(New MailAddress(" you@yourprovider.com ", “john")) Dim mySmtpClient As SmtpClient = New SmtpClient() mySmtpClient.Send(myMessage) lblMessage.Visible = True FormTable.Visible = False End If Practice – Sending mail from the ContactForm User Control Save all your changes and request Contact.aspx in the browser. Enter your details and click the Send button. You’ll see the text Message Sent appear Check your email account after a while; you should receive an email message