"
ASP.NET (snapshot 2017) Microsoft documentation and samples

Iteration #3 – Add form validation (VB)

by Microsoft

Download Code

In the third iteration, we add basic form validation. We prevent people from submitting a form without completing required form fields. We also validate email addresses and phone numbers.

Building a Contact Management ASP.NET MVC Application (VB)

In this series of tutorials, we build an entire Contact Management application from start to finish. The Contact Manager application enables you to store contact information - names, phone numbers and email addresses - for a list of people.

We build the application over multiple iterations. With each iteration, we gradually improve the application. The goal of this multiple iteration approach is to enable you to understand the reason for each change.

This Iteration

In this second iteration of the Contact Manager application, we add basic form validation. We prevent people from submitting a contact without entering values for required form fields. We also validate phone numbers and email addresses (see Figure 1).

The New Project dialog box

Figure 01: A form with validation (Click to view full-size image)

In this iteration, we add the validation logic directly to the controller actions. In general, this is not the recommended way to add validation to an ASP.NET MVC application. A better approach is to place an application s validation logic in a separate service layer. In the next iteration, we refactor the Contact Manager application to make the application more maintainable.

In this iteration, to keep things simple, we write all of the validation code by hand. Instead of writing the validation code ourselves, we could take advantage of a validation framework. For example, you can use the Microsoft Enterprise Library Validation Application Block (VAB) to implement the validation logic for your ASP.NET MVC application. To learn more about the Validation Application Block, see:

http://msdn.microsoft.com/en-us/library/dd203099.aspx

Adding Validation to the Create View

Let s start by adding validation logic to the Create view. Fortunately, because we generated the Create view with Visual Studio, the Create view already contains all of the necessary user interface logic to display validation messages. The Create view is contained in Listing 1.

Listing 1 - .aspx

[!code-aspxMain]

   1:  <%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ContactManager.Contact)" %>
   2:   
   3:  <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
   4:  <title>Create</title>
   5:  </asp:Content>
   6:   
   7:  <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   8:   
   9:      <%= Html.ValidationSummary() %>
  10:   
  11:      <% Using Html.BeginForm()%>
  12:   
  13:          <fieldset>
  14:              <legend>Create New Contact</legend>
  15:              <p>
  16:                  <label for="FirstName">First Name:</label>
  17:                  <%= Html.TextBox("FirstName") %>
  18:                  <%= Html.ValidationMessage("FirstName", "*") %>
  19:              </p>
  20:              <p>
  21:                  <label for="LastName">Last Name:</label>
  22:                  <%= Html.TextBox("LastName") %>
  23:                  <%= Html.ValidationMessage("LastName", "*") %>
  24:              </p>
  25:              <p>
  26:                  <label for="Phone">Phone:</label>
  27:                  <%= Html.TextBox("Phone") %>
  28:                  <%= Html.ValidationMessage("Phone", "*") %>
  29:              </p>
  30:              <p>
  31:                  <label for="Email">Email:</label>
  32:                  <%= Html.TextBox("Email") %>
  33:                  <%= Html.ValidationMessage("Email", "*") %>
  34:              </p>
  35:              <p class="submit">
  36:                  <input type="submit" value="Create" />
  37:              </p>
  38:          </fieldset>
  39:   
  40:      <% End Using %>
  41:   
  42:  </asp:Content>

The field-validation-error class is used to style the output rendered by the Html.ValidationMessage() helper. The input-validation-error class is used to style the textbox (input) rendered by the Html.TextBox() helper. The validation-summary-errors class is used to style the unordered list rendered by the Html.ValidationSummary() helper.

[!NOTE]

You can modify the style sheet classes described in this section to customize the appearance of validation error messages.

Adding Validation Logic to the Create Action

Right now, the Create view never displays validation error messages because we have not written the logic to generate any messages. In order to display validation error messages, you need to add the error messages to ModelState.

[!NOTE]

The UpdateModel() method adds error messages to ModelState automatically when there is an error assigning the value of a form field to a property. For example, if you attempt to assign the string “apple” to a BirthDate property that accepts DateTime values, then the UpdateModel() method adds an error to ModelState.

The modified Create() method in Listing 2 contains a new section that validates the properties of the Contact class before the new contact is inserted into the database.

Listing 2 - Controllers.vb (Create with validation)

[!code-vbMain]

   1:  <AcceptVerbs(HttpVerbs.Post)> _
   2:  Function Create(<Bind(Exclude:="Id")> ByVal contactToCreate As Contact) As ActionResult
   3:      ' Validation logic
   4:      If contactToCreate.FirstName.Trim().Length = 0 Then
   5:          ModelState.AddModelError("FirstName", "First name is required.")
   6:      End If
   7:      If contactToCreate.LastName.Trim().Length = 0 Then
   8:          ModelState.AddModelError("LastName", "Last name is required.")
   9:      End If
  10:      If (contactToCreate.Phone.Length > 0 AndAlso Not Regex.IsMatch(contactToCreate.Phone, "((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
  11:          ModelState.AddModelError("Phone", "Invalid phone number.")
  12:      End If        
  13:      If (contactToCreate.Email.Length > 0 AndAlso  Not Regex.IsMatch(contactToCreate.Email, "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
  14:          ModelState.AddModelError("Email", "Invalid email address.")
  15:      End If
  16:      If Not ModelState.IsValid Then
  17:          Return View()
  18:      End If
  19:   
  20:      ' Database logic
  21:      Try
  22:          _entities.AddToContactSet(contactToCreate)
  23:          _entities.SaveChanges()
  24:          Return RedirectToAction("Index")
  25:      Catch
  26:          Return View()
  27:      End Try
  28:  End Function

The validate section enforces four distinct validation rules:

When there is a validation rule violation, an error message is added to ModelState with the help of the AddModelError() method. When you add a message to ModelState, you provide the name of a property and the text of a validation error message. This error message is displayed in the view by the Html.ValidationSummary() and Html.ValidationMessage() helper methods.

After the validation rules are executed, the IsValid property of ModelState is checked. The IsValid property returns false when any validation error messages have been added to ModelState. If validation fails, the Create form is redisplayed with the error messages.

[!NOTE]

I got the regular expressions for validating the phone number and email address from the regular expression repository at http://regexlib.com

Adding Validation Logic to the Edit Action

The Edit() action updates a Contact. The Edit() action needs to perform exactly the same validation as the Create() action. Instead of duplicating the same validation code, we should refactor the Contact controller so that both the Create() and Edit() actions call the same validation method.

The modified Contact controller class is contained in Listing 3. This class has a new ValidateContact() method that is called within both the Create() and Edit() actions.

Listing 3 - Controllers.vb

[!code-vbMain]

   1:  Public Class ContactController
   2:      Inherits System.Web.Mvc.Controller
   3:   
   4:      Private _entities As New ContactManagerDBEntities()
   5:   
   6:      Protected Sub ValidateContact(contactToValidate As Contact)
   7:          If contactToValidate.FirstName.Trim().Length = 0 Then
   8:              ModelState.AddModelError("FirstName", "First name is required.")
   9:          End If
  10:          If contactToValidate.LastName.Trim().Length = 0 Then
  11:              ModelState.AddModelError("LastName", "Last name is required.")
  12:          End If
  13:          If (contactToValidate.Phone.Length > 0 AndAlso Not Regex.IsMatch(contactToValidate.Phone, "((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
  14:              ModelState.AddModelError("Phone", "Invalid phone number.")
  15:          End If        
  16:          If (contactToValidate.Email.Length > 0 AndAlso  Not Regex.IsMatch(contactToValidate.Email, "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
  17:              ModelState.AddModelError("Email", "Invalid email address.")
  18:          End If
  19:      End Sub
  20:   
  21:      '
  22:      ' GET: /Contact
  23:   
  24:      Function Index() As ActionResult
  25:          Return View(_entities.ContactSet.ToList())
  26:      End Function
  27:   
  28:      '
  29:      ' GET: /Contact/Create
  30:   
  31:      Function Create() As ActionResult
  32:          Return View()
  33:      End Function
  34:   
  35:      '
  36:      ' POST: /Contact/Create
  37:   
  38:      <AcceptVerbs(HttpVerbs.Post)> _
  39:      Function Create(<Bind(Exclude:="Id")> ByVal contactToCreate As Contact) As ActionResult
  40:          ' Validation logic
  41:          ValidateContact(contactToCreate)
  42:          If Not ModelState.IsValid Then
  43:              Return View()
  44:          End If
  45:   
  46:          ' Database logic
  47:          Try
  48:              _entities.AddToContactSet(contactToCreate)
  49:              _entities.SaveChanges()
  50:              Return RedirectToAction("Index")
  51:          Catch
  52:              Return View()
  53:          End Try
  54:      End Function
  55:   
  56:      '
  57:      ' GET: /Contact/Edit/5
  58:   
  59:      Function Edit(ByVal id As Integer) As ActionResult
  60:          Dim contactToEdit = (from c in _entities.ContactSet _
  61:                             where c.Id = id _
  62:                             select c).FirstOrDefault()
  63:   
  64:          Return View(contactToEdit)
  65:      End Function
  66:   
  67:      '
  68:      ' POST: /Contact/Edit/5
  69:   
  70:      <AcceptVerbs(HttpVerbs.Post)> _
  71:      Function Edit(ByVal contactToEdit As Contact) As ActionResult
  72:          ' Validation logic
  73:          ValidateContact(contactToEdit)
  74:          If Not ModelState.IsValid Then
  75:              Return View()
  76:          End If
  77:   
  78:          ' Database logic
  79:          Try
  80:              Dim originalContact = (from c in _entities.ContactSet _
  81:                               where c.Id = contactToEdit.Id _
  82:                               select c).FirstOrDefault()
  83:              _entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit)
  84:              _entities.SaveChanges()
  85:              Return RedirectToAction("Index")
  86:          Catch
  87:              Return View()
  88:          End Try
  89:      End Function
  90:   
  91:      '
  92:      ' GET: /Contact/Delete/5
  93:   
  94:      Function Delete(ByVal id As Integer) As ActionResult
  95:          Dim contactToDelete = (from c in _entities.ContactSet _
  96:                             where c.Id = id _
  97:                             select c).FirstOrDefault()
  98:   
  99:          Return View(contactToDelete)
 100:      End Function
 101:   
 102:      '
 103:      ' POST: /Contact/Delete/5
 104:   
 105:      <AcceptVerbs(HttpVerbs.Post)> _
 106:      Function Delete(ByVal contactToDelete As Contact) As ActionResult
 107:          Try
 108:              Dim originalContact = (from c in _entities.ContactSet _
 109:                               where c.Id = contactToDelete.Id _
 110:                               select c).FirstOrDefault()
 111:              _entities.DeleteObject(originalContact)
 112:              _entities.SaveChanges()
 113:              Return RedirectToAction("Index")
 114:          Catch
 115:              Return View()
 116:          End Try
 117:      End Function
 118:   
 119:  End Class

Summary

In this iteration, we added basic form validation to our Contact Manager application. Our validation logic prevents users from submitting a new contact or editing an existing contact without supplying values for the FirstName and LastName properties. Furthermore, users must supply valid phone numbers and email addresses.

In this iteration, we added the validation logic to our Contact Manager application in the easiest way possible. However, mixing our validation logic into our controller logic will create problems for us in the long term. Our application will be more difficult to maintain and modify over time.

In the next iteration, we will refactor our validation logic and database access logic out of our controllers. We’ll take advantage of several software design principles to enable us to create a more loosely coupled, and more maintainable, application.

Previous Next



Comments ( )
Link to this page: //www.vb-net.com/AspNet-DocAndSamples-2017/aspnet/mvc/overview/older-versions-1/contact-manager/iteration-3-add-form-validation-vb.htm
< THANKS ME>