Chapter 4. Validating Web Form Pages

If you want to collect information from the users of your application, you’ll most likely need to implement some type of form validation. For example, you’ll need a way to make certain form fields required and prevent users from entering the wrong type of information into them.

Fortunately, Visual Studio .NET makes it easy to validate form data. You can add a variety of Validation controls to your Web Form Page to prevent the wrong type of data from being submitted.

In this chapter, you’ll learn

  • How to use the common properties shared by all Validation controls

  • How to use the Validation controls to check for required fields, check for the correct data type, or perform custom validation tasks

  • How to display a summary of validation errors in a Web Form Page

Overview of the Validation Controls

There are five standard Validation Web controls that you can add to a Web Form Page to validate form data:

  • CompareValidatorEnables you to validate the data in a form field against a fixed value or other form field

  • CustomValidatorEnables you to validate the data in a form field by using a custom subroutine

  • RangeValidatorEnables you to validate the data in a form field against a minimum and maximum value

  • RegularExpressionValidatorEnables you to validate the data in a form field against a regular expression

  • RequiredFieldValidatorEnables you to validate the data in a form field by checking whether the form field contains a value

All of the Validation controls support three properties—the ControlToValidate property, Text property, and IsValid property. All the Validation controls derive from the BaseValidator class.

The ControlToValidate property contains the ID of the form control that you want to validate. For example, suppose that you want to create a text box in a Web Form Page named txtPassword and you don’t want a user to be able to submit the form without entering a value for the TextBox control. In that case, you would add a RequiredFieldValidator control to the page and assign the value txtPassword to the RequiredFieldValidator control’s ControlToValidate property.

The second property that all Validation controls share is the Text property. You assign the error message that you want the Validation control to display to the Text property. For example, you might assign the value You must enter a password! to the Text property of a RequiredFieldValidator control. Whatever error message you assign to the Text property appears at the same location as the Validation control on a page.

Finally, all Validation controls have an IsValid property. The IsValid property has the value True when the control indicated by the ControlToValidate property passes the validation test. Otherwise, this property has the value False. You can use this property to determine the nature of the particular validation errors contained in a Web Form Page.

Post Backs and Form Validation

If you have worked with HTML forms in the past, you are probably used to creating forms that post to a new page. To take advantage of Validation controls in a Web Form Page, however, you cannot post the form information to a new page. Instead, you must post the Web Form Page back to the same page on the Web server.

For example, suppose that you want to add two Web Form Pages to a project—a page named Register.aspx and a page named ThankYou.aspx. The Register.aspx page contains a registration form and the ThankYou.aspx page contains a thank you message for registering.

When designing your project, you might be tempted to have the Register.aspx page post the form to the ThankYou.aspx page. The user fills out the registration form, submits it, and receives a thank you message. However, you can’t take advantage of Validation controls in the Register.aspx page when you post a form to a new page.

Instead, the Register.aspx page should post back to itself. This way, you can display error messages with any Validation controls that you have added to the form. When there are no validation errors in the Register.aspx page, you can explicitly redirect the user to the ThankYou.aspx page.

By default, Web Form Pages automatically post back to themselves. However, you must explicitly add the code to the Web Form to redirect the user to a new page when there are no validation errors in the page. You’ll see several examples of how to do this when we discuss the individual Validation controls.

JavaScript and the Validation Controls

When you use the Validation controls with Microsoft Internet Explorer 4.0 or later, the Validation controls will automatically use client-side JavaScript. This means that the Validation controls can immediately display error messages on the browser while the user is in the process of completing a form. If there are any validation errors in a page, the client-side JavaScript will prevent the user from submitting the form back to the server.

If you are not using Microsoft Internet Explorer 4.0 or later, you can still use the Validation controls. The Validation controls will “fall back” to performing validation on the server after the form is submitted to the Web server. Validation error messages won’t be displayed immediately, but they will appear after the page is posted back to the Web server.

Using Validation Controls

All the Validation controls can be found under the Web Forms tab in the Toolbox. Because these controls are Web controls, you can add them only to Web Form Pages and not to other types of pages, such as HTML pages.

Furthermore, the Validation controls only work with server controls, such as the TextBox control. You cannot use the Validation controls with standard HTML text fields.

In the following sections, you’ll learn how to take advantage of each of the Validation controls to perform common form validation tasks.

Checking for Required Fields

You can use the RequiredFieldValidator control to automatically display an error message when you submit a form with an empty form field. For example, you can use the RequiredFieldValidator control with a login form to prevent users from submitting the form when values have not been entered for the username and password form fields.

The RequiredFieldValidator has two important properties that you need to set:

  • ControlToValidateThe form field to validate

  • TextThe error message to display

To create a login form with a required username form field, complete the following steps.

First, you need to create the necessary form elements:

  1. Create a new Web Form Page named Login.aspx.

  2. Add an HTML Label to the Web Form Page and assign it the text Username.

  3. Add a TextBox control to the Web Form Page.

  4. Add a RequiredFieldValidator control to the Web Form. Assign the following two properties to the control:

    Property

    Value

    Text

    Required!

    ControlToValidate

    TextBox1

  5. Add a Button control to the Web Form Page.

Next, you need to add the code that executes when you click the Button control:

  1. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    

Finally, you need to add the success page to your project and compile the pages:

  1. Add a new Web Form Page to your project named Success.aspx.

  2. Add an HTML Label to the Success.aspx page and enter the text Thank you for completing the form! into the label.

  3. Right-click the Login.aspx page in the Solution Explorer window and select Build and Browse.

If you attempt to submit the Login.aspx page by clicking the Button control and you don’t enter a username, the error message in Figure 4.1 is displayed. However, if you enter a value into the username text box and submit the form, you are automatically redirected to the Success.aspx page.

Using the RequiredFieldValidator control.

Figure 4.1. Using the RequiredFieldValidator control.

When you click the Button control, the Button1_Click event handler executes. This subroutine contains the following code:

C#

private void Button1_Click(object sender, System.EventArgs e)
{
  if (Page.IsValid)
    Response.Redirect( "success.aspx" );
}

VB.NET

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
VB.NET Handles Button1.Click
  If IsValid Then
    Response.Redirect("Success.aspx")
  End If
End Sub

The IsValid property has the value True when there are no validation errors in the form. If there are no validation errors, the Response.Redirect method is used to automatically redirect the user to the Success.aspx page. Otherwise, the Login.aspx page is redisplayed and the user can see any validation error messages.

Validating a Range of Expressions

You can use the RangeValidator control to specify a minimum and maximum value for a TextBox control. You can use this control to check for a range of integers, currency amounts, dates, strings, or doubles.

The RangeValidator control has five important properties:

  • ControlToValidateThe form field to validate

  • MinimumValueThe minimum valid value in the range of values

  • MaximumValueThe maximum valid value in the range of values

  • TextThe error message to display

  • TypeThe type of comparison to perform (possible values are String, Integer, Double, Date, Currency)

For example, suppose that you want to add an Age text box to a Web Form Page. In that case, you might want to prevent a user from entering an age less than 2 or greater than 120.

To use the RangeValidator control with an Age text box, perform the following steps.

First, you need to add the necessary controls to the page:

  1. Create a new Web Form Page named Register.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Age.

  3. Add a TextBox control to the Web Form Page.

  4. Add a RangeValidator control to the Web Form Page and assign the following properties to it:

    Property

    Value

    Text

    Out of Range!

    ControlToValidate

    TextBox1

    MinimumValue

    2

    MaximumValue

    120

    Type

    Integer

  5. Add a Button control to the Web Form Page.

Next, you need to add the code that executes when you click the Button control:

  1. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    
  3. Right-click the Register.aspx page in the Solution Explorer window and select Build and Browse.

If you enter a value less than 2 or greater than 120 into the Age text box and submit the form, an error message will be displayed by the RangeValidator (see Figure 4.2). Otherwise, the Button1_Click event handler will execute and redirect you to the Success.aspx page (we created the Success.aspx page in the previous section).

Using the RangeValidator control.

Figure 4.2. Using the RangeValidator control.

Tip

If you don’t enter a value into the text box and submit the form, the RangeValidator control will not display an error message. If you want to require a value for a control, you must add both a RangeValidator and RequiredFieldValidator control to the Web Form Page.

Comparing Values

You can use the CompareValidator to compare the value of one control to another control or to compare the value of one control to a fixed value. The CompareValidator has six important properties:

  • ControlToValidateThe form field to validate

  • ControlToCompareThe form field to perform the comparison against

  • OperatorThe operator used for the comparison (possible values are Equal, NotEqual, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, and DataTypeCheck)

  • TextThe error message to display

  • TypeThe type of comparison to perform (possible values are String, Integer, Double, Date, Currency)

  • ValueToCompareThe fixed value to compare

For example, suppose that you are building a Web application to schedule meetings. The form might contain a field for entering the starting time of the meeting and a second field for entering the ending time of the meeting. You could use the CompareValidator to ensure that the time entered into the second field occurs after the time entered into the first field.

Or, suppose that you have only one form field for entering a meeting date. In that case, you might want to check that the date entered into the field occurs after the current date and time (you can’t retroactively schedule meetings).

To use the CompareValidator to check whether a value entered into a field occurs after the current date and time, perform the following steps.

First, you need to add the necessary controls to the page:

  1. Create a new Web Form Page named Schedule.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Meeting Date into the label.

  3. Add a TextBox control to the Web Form Page.

  4. Add a CompareValidator control to the Web Form Page and assign the following values to its properties:

    Property

    Value

    Text

    Bad Date!

    ControlToValidate

    TextBox1

    Operator

    GreaterThan

    Type

    Date

  5. Add a Button control to the Web Form Page.

Next, you need to add the necessary code for both the Page_Load and Button_Click event handlers:

  1. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    
  3. Enter the following code for the Page_Load() method:

    C#

    private void Page_Load(object sender, System.EventArgs e)
    {
      CompareValidator1.ValueToCompare = DateTime.Now.ToString("d");
    }
    

    VB.NET

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
    VB.NET MyBase.Load
      CompareValidator1.ValueToCompare = DateTime.Now
    End Sub
    
  4. Right-click the Schedule.aspx page in the Solution Explorer window and select Build and Browse.

The current date is assigned to the CompareValidator control’s ValueToCompare property within the Page_Load event handler. If you enter a date that is not greater than the current date into the text box and submit the form, you’ll receive the error message displayed in Figure 4.3.

Comparing values with the CompareValidator control.

Figure 4.3. Comparing values with the CompareValidator control.

Tip

Like the RangeValidator, if you don’t enter a value into the text box and submit the form, the CompareValidator control will not display an error message. If you want to require a value for a control, you must add both a CompareValidator and RequiredFieldValidator control to the Web Form Page.

Performing Data Type Checks

One common validation task involves checking whether the right type of data was entered into a form field. For example, you do not want users entering the text “apple” into a form field labeled Birth Date.

You can use the CompareValidator to perform data type checks by assigning the value DataTypeCheck to the CompareValidator control’s Operator property.

To prevent a user from entering the wrong type of value into a Birth Date field, perform the following steps.

First, you need to add the necessary controls to the page:

  1. Create a new Web Form Page named Survey.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Birth Date into the Label

  3. Add a TextBox control to the Web Form Page.

  4. Add a CompareValidator control to the Web Form Page.

  5. In the Properties window, select the CompareValidator control and assign the following values to its properties:

    Property

    Value

    Text

    Invalid Date!

    ControlToValidate

    TextBox1

    Operator

    DataTypeCheck

    Type

    Date

  6. Add a Button control to the Web Form Page.

Next, you need to add the code that executes when you click the Button control:

  1. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    

After you complete these steps, you’ll receive an error if you attempt to enter anything except a date into the Birth Date form field (see Figure 4.4).

Checking the data type of a form field.

Figure 4.4. Checking the data type of a form field.

The CompareValidator is very picky about the format of acceptable dates. You are allowed to enter dates by using a short date format, such as 12/25/1966. Other date formats, such as December 12, 1966, will fail.

Regular Expression Validation

You can use the RegularExpressionValidator to check whether the value of a form field matches a specified pattern. For example, you can use this Validation control to validate Social Security numbers, postal codes, phone numbers, and email addresses.

Regular expressions are a complex topic that falls outside the scope of this book. Fortunately, however, you don’t need to understand regular expressions to take advantage of the RegularExpressionValidator. Visual Studio .NET provides you with several prewritten regular expressions.

The RegularExpressionValidator has three important properties:

  • ControlToValidateThe form field to validate

  • TextThe error message to display

  • ValidationExpressionThe regular expression pattern to match

You can supply any regular expression pattern that you want for the ValidationExpression property. Alternatively, you can use one of the predefined regular expression patterns supplied with Visual Studio .NET. If you add a RegularExpressionValidator control to a page and click the ellipses next to the ValidationExpression property, the Regular Expression Editor dialog box in Figure 4.5 appears.

The Regular Expression Editor.

Figure 4.5. The Regular Expression Editor.

For example, suppose that you need to validate a Phone Number form field by using the RegularExpressionValidator. To do so, perform the following steps:

  1. Create a new Web Form Page named CustomerInfo.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Phone Number into the label.

  3. Add a TextBox control to the Web Form Page.

  4. Add a RegularExpressionValidator control to the Web Form Page and assign the following values to its properties:

    Property

    Value

    Text

    Invalid Phone Number!

    ControlToValidate

    TextBox1

  5. In the Properties window, click the ellipsis next to the ValidationExpression property to open the Regular Expression Editor dialog box.

  6. In the Regular Expression dialog box, click U.S. Phone Number and click OK.

  7. Add a Button control to the Web Form Page.

Next, you need to add the code that executes when you click the Button control:

  1. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    
  3. Right-click the CustomerInfo.aspx page in the Solution Explorer window and select Build and Browse.

If you attempt to enter a phone number that has an invalid pattern into the text box, you’ll receive the error displayed in Figure 4.6.

Using the RegularExpressionValidator control.

Figure 4.6. Using the RegularExpressionValidator control.

Tip

Like the other Validation controls, if you don’t enter a value into the text box and submit the form, the RegularExpressionValidator control will not display an error message. If you want to require a value for a control, you must add both a RegularExpressionValidator and RequiredFieldValidator control to the Web Form Page.

Performing Custom Validation

If you need to validate a form field and none of the standard Validation controls perform the necessary type of validation, you can use the CustomValidator control to perform any type of validation that you might desire.

You can associate the CustomValidator control with a custom event handler. The custom validation event handler contains your validation logic.

For example, suppose that you don’t want users to enter more than 10 characters in a multi-line text box. In that case, you can associate an event handler with the CustomValidator control that returns an error when the TextBox control contains too many characters. To do so, perform the following steps:

Note

You cannot use the MaxLength property to limit the number of characters that a user can enter into a multi-line text box because the MaxLength property does not work with a multiline text box.

  1. Create a new Web Form Page named ShortForm.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Comments into the label.

  3. Add a TextBox control to the Web Form Page and assign the value MultiLine to the control’s TextMode property.

  4. Add a CustomValidator control to the Web Form Page and assign the following values to its properties:

    Property

    Value

    Text

    Comments Too Long!

    ControlToValidate

    TextBox1

Next, you need to add the custom validation function by adding an event handler for the CustomValidator control:

  1. Add a CustomValidator1_ServerValidate() method by double-clicking the CustomValidator control on the Designer surface. This will switch you to the Code Editor.

  2. Enter the following code for the CustomValidator1_ServerValidate() subroutine:

    C#

    private void CustomValidator1_ServerValidate(object source, System.Web.UI.WebControls
    C#.ServerValidateEventArgs args)
    {
      if (args.Value.Length > 10)
        args.IsValid = false;
      else
        args.IsValid = true;
    }
    

    VB.NET

    Private Sub CustomValidator1_ServerValidate(ByVal source As System.Object, ByVal args As
    VB.NET System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
    If args.Value.Length > 10 Then
        args.IsValid = False
      Else
        args.IsValid = True
      End If
    End Sub
    

Next, you need to add a Button control and an event handler for the Button control:

  1. Switch back to the Designer by selecting View, Designer.

  2. Add a Button1_Click() method to the Web Form Page by double-clicking the Button control on the Designer surface. This will switch you to the Code Editor.

  3. Enter the following code for the Button1_Click() method:

    C#

    private void Button1_Click(object sender, System.EventArgs e)
    {
      if (Page.IsValid)
        Response.Redirect( "success.aspx" );
    }
    

    VB.NET

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    VB.NET Handles Button1.Click
      If IsValid Then
        Response.Redirect("Success.aspx")
      End If
    End Sub
    
  4. Right-click the ShortForm.aspx page in the Solution Explorer window and select Build and Browse.

If you attempt to add more than 10 characters to the text box, and you submit the form, the error in Figure 4.7 will be displayed.

Using the CustomValidator control.

Figure 4.7. Using the CustomValidator control.

The custom validation subroutine looks like the following:

C#

private void CustomValidator1_ServerValidate(object source, System.Web.UI.WebControls
C#.ServerValidateEventArgs args)
{
  if (args.Value.Length > 10)
    args.IsValid = false;
  else
    args.IsValid = true;
}

VB.NET

Private Sub CustomValidator1_ServerValidate(ByVal source As System.Object, ByVal args As
VB.NET System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
If args.Value.Length > 10 Then
    args.IsValid = False
  Else
    args.IsValid = True
  End If
End Sub

The second parameter passed to the ServerValidate subroutine has two properties—the Value property and IsValid property. The Value property contains whatever text was entered into the control being validated. In our custom validation handler, we check the length of the Value property to check whether more than 10 characters were entered into the multi-line text box.

You use the IsValid property to indicate whether or not the validation check was successful. If you assign the value False to the IsValid property, the CustomValidator control will display an error message.

Warning

The CustomValidator that we created in this section uses a server-side validation subroutine. The subroutine will not execute until the form is posted back to the server. If the form contains other Validation controls that use client-side validation, such as the RequiredFieldValidator, the error message displayed by the CustomValidator will not be displayed until all the other validation errors in the Web Form Page are fixed.

Displaying a Summary of Validation Errors

If you are creating a long form that uses several Validation controls, it might be difficult for someone completing the form to see all the validation error messages. For example, if the form has 50 form fields and there is a single validation error that appears next to the 48th form field, the person completing the form may never see it.

You can display a summary of all the validation error messages for a Web Form Page in a single location by using the ValidationSummary control.

To take advantage of the ValidationSummary control, you need to provide a value for the ErrorMessage property for each Validation control on a page. The ErrorMessage property contains the error that the ValidationSummary control displays when there is an error.

It is important to not confuse a Validation control’s Text property with its ErrorMessage property. The message assigned to the Text property appears at the same location on the Web Form Page as the Validation control. On the other hand, the message assigned to the ErrorMessage property is displayed as part of the summary displayed by the ValidationSummary control.

Typically, you’ll want to supply a different error message for the Text and ErrorMessage properties. For example, for the text property, you might assign the message “First name is required!” for the ErrorMessage property.

For example, suppose that you need to create a simple pizza order form with two required form fields—the customer name and customer phone number. Additionally, suppose that you want to display a summary of validation errors at the top of the pizza order form. To do so, perform the following steps:

  1. Create a new Web Form Page named PizzaOrder.aspx.

  2. Add an HTML Label to the Web Form Page and enter the text Customer Name into the label.

  3. Add a TextBox control to the Web Form Page.

  4. Add a RequiredFieldValidator control to the Web Form Page and enter the following values for its properties:

    Property

    Value

    ControlToValidate

    TextBox1

    Text

    Required!

    ErrorMessage

    Customer Name is Required!

  5. Add a second HTML Label to the Web Form Page and enter the text Customer Phone Number into the label.

  6. Add a second TextBox control to the Web Form Page.

  7. Add a second RequiredFieldValidator control to the Web Form Page and enter the following values for its properties:

    Property

    Value

    ControlToValidate

    TextBox2

    Text

    Required!

    ErrorMessage

    Customer Phone Number is Required!

  8. Add a ValidationSummary control to the top of the Web Form Page.

  9. Add a Button control to the Web Form Page.

  10. Right-click the PizzaOrder.aspx page in the Solution Explorer window and select Build and Browse.

If you attempt to submit the form in the PizzaOrder.aspx page without entering a value for the Customer Name and Customer Phone number fields, validation errors will appear in two places. Each of the two RequiredFieldValidator controls will display the error message Required!. Furthermore, the ValidationSummary control will display the error messages Customer Name is Required! and Customer Phone Number is Required! (see Figure 4.8).

Using the ValidationSummary control.

Figure 4.8. Using the ValidationSummary control.

Summary

In this chapter, you learned how to validate the form fields contained in a Web Form Page. First you were provided with an overview of the common properties shared by all the standard Validation controls. You also learned how the Validation controls support client-side JavaScript when used with Internet Explorer 4.0 or later.

Next, you created pages that use each of the Validation controls. You learned how to use the RequiredFieldValidator control to check for required fields, the RangeValidator control to check for a minimum and maximum value, the CompareValidator control to compare values, the RegularExpressionValidator control to validate email addresses and phone numbers, and the CustomValidator control to execute a custom validation subroutine.

Finally, you learned how to display a summary of validation error messages in a page by taking advantage of the ValidationSummary control.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset