Form Validations In ASP.NET

Hey, there! When working with web forms in applications with ASP.NET, it is important to be able to validate the data that can be sent to the server for storage or modification.
 
In this new entry, we'll learn how to validate forms set with DotVVM so that asterisks or validation messages can be displayed for a specified field.
 

Example for validations on forms

 
To understand how validations work on forms in an ASP.NET DotVVM, let's look at an example. Let's say we have a page for registering and authenticating users, and we want you to validate the fields in these forms.
 
The page would be displayed as follows,
 
Form Validations in ASP.NET
 
However, as it is well known, DotVVM is based on the MVVM pattern (Model, View, ViewModel), when using classes with C- and visual elements with HTML. In this sense, let's look at each of these parts.
 

Model

 
First, in this section, we can establish data models that represent the information that users will send to the application through a web form. This 'Model' shall provide as much validation information as possible about the data that comprises it using metadata definition attributes (DataAnnotations).
 
Given these considerations, we may encounter one model for the user authentication section, and another for registration. About the registration model, this would look like this,
  1. public class CreateAccountForm : IValidatableObject  
  2. {  
  3.     [Required]  
  4.     public string Name { getset; }  
  5.   
  6.     [Required]  
  7.     [EmailAddress]  
  8.     public string Email { getset; }  
  9.   
  10.     [Required]  
  11.     [MinLength(8)]  
  12.     public string Password { getset; }  
  13.   
  14.     [Required]  
  15.     [Compare(nameof(Password))]  
  16.     public string Password2 { getset; }  
  17.   
  18.     public bool AgreeWithConditions { getset; }  
  19.   
  20.     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)  
  21.     {  
  22.         if (!AgreeWithConditions)  
  23.         {  
  24.             yield return new ValidationResult(  
  25.                 "You need to agree with terms & conditions.",  
  26.                 new[] { nameof(AgreeWithConditions) }  
  27.             );  
  28.         }  
  29.     }  
  30. }  
With ASP.NET data annotations, we can find for example the annotation [Required], which allows you to set an attribute to be required when filling out a form. We can also set the minimum or maximum length that an attribute can have, validate that the field has a certain format, for example, email formats, credit cards, phone numbers, among others.
 
All the annotations that we can consider in .NET 5 can be queried at the following address - System.ComponentModel.DataAnnotations Namespace.
 
Within the model, we can also establish our own validations, for example, in this case, it can be verified that the user is in accordance with the terms and conditions at the time of registration. If validation is not met, a custom error message can be set.
 

ViewModel

 
Now, in the ViewModel we need to set the objects that will allow us to store the collected data in the login and registration forms,
  1. public SignInForm SignInForm { getset; } = new SignInForm();  
  2. public CreateAccountForm CreateAccountForm { getset; } = new CreateAccountForm();  
Finally, we will also have to set the methods that allow us to perform the user-startup and registration operation. About the method to start the session, in the project we can find something like this,
  1. public void SignIn()  
  2. {  
  3.     // this code actually doesn't sign anyone in - it's just a validation demo  
  4.     // you can use e.g. SignInManager.PasswordSignInAsync from ASP.NET Core Identity  
  5.   
  6.     if (SignInForm.Email == "info@dotvvm.com" && SignInForm.Password == "Password1234")  
  7.     {  
  8.         Context.RedirectToRoute("Success");  
  9.     }  
  10.     else  
  11.     {  
  12.         // TODO: report invalid credentials  
  13.         Context.ModelState.Errors.Add(new ViewModelValidationError()  
  14.         {  
  15.             ErrorMessage = "Incorrect credentials."  
  16.         });  
  17.         Context.FailOnInvalidModelState();  
  18.     }  
  19. }  
An interesting aspect to mention is that we can work with a ModelState. This object allows us to perform additional validation checks on the method itself, and report additional validation errors to the user. This is used to perform validations that require access to the SQL database, for example, to review a user's credentials are correct (this is an example for illustrative purposes).
 

View

 
With models and view models set, we can now structure our HTML forms with DotVVM controls set for this purpose. For this case, let's look at the code for the login form,
  1. <form DataContext="{value: SignInForm}">  
  2.     <div class="form-group">  
  3.         <label for="signin-email">E-mail address</label>  
  4.         <dot:TextBox Type="email"  
  5.                         ID="signin-email"  
  6.                         class="form-control"  
  7.                         Text="{value: Email}"                                           
  8.                         Validator.Value="{value: Email}"  
  9.                         placeholder="Enter your e-mail" />  
  10.   
  11.     </div>  
  12.     <div class="form-group">  
  13.         <label for="signin-password">Password</label>  
  14.         <dot:TextBox Type="Password"  
  15.                         ID="signin-password"  
  16.                         class="form-control"   
  17.                         Text="{value: Password}"  
  18.                         Validator.Value="{value: Password}"  
  19.                         placeholder="Password" />  
  20.     </div>  
  21.   
  22.     <dot:ValidationSummary Validation.Target="{value: _this}"  
  23.                             IncludeErrorsFromTarget="true"  
  24.                             HideWhenValid="true"  
  25.                             class="alert alert-danger"/>  
  26.   
  27.     <dot:Button IsSubmitButton="true"   
  28.                 ButtonTagName="button"  
  29.                 class="btn btn-primary"  
  30.                 Click="{command: _root.SignIn()}"  
  31.                 Validation.Target="{value: _this}">  
  32.         Sign In  
  33.     </dot:Button>  
  34. </form>  
Here we can find two TextBoxes, the first for email, and the second for the user's password. In this type of control, we can put the Validator attribute, where we must specify the value that we want to validate, for example: Validator.Value="{value: Email}. Here validation will be performed in accordance with the provisions of the model.
 
We can also display an error summary with the ValidationSummary control, according to the Validators set within the form.
 
In an example scenario, we might encounter the following case,
 
Form Validations in ASP.NET
 
Where the email entered is not in the correct format, and the password field is empty. These validations have been performed in accordance with the annotations in the model.
 
In another scenario, we might encounter the following,
 
Form Validations in ASP.NET
 
In this case, it was because the credentials entered are incorrect. This validation was done in the method to log in with the ModelState for custom validations.
 
And in this quick and easy way, we will be able to validate our web forms within ASP.NET with DotVVM.
 
The source code for this example is available in this GitHub repository: DotvvmValidationSample.
 
Additional Resources
 
If you like to continue acquiring or reinforcing knowledge in this area, here are some additional resources that can be very useful:
Thank you very much for reading this article, I hope that this demo can be of help for the organization and dissemination of events. If you have any questions or ideas that you need to discuss, it will be nice to be able to collaborate and together exchange knowledge with each other.
 
If you like, we can stay in touch on Twitter, or on Telegram too. :)