Understand Validation In Blazor Apps

Introduction

 
Input validation is very important for any application, as it prevents users from posting unwanted or erroneous data to the server. Blazor supports form and validation using data annotation. One of the key advantages of using data annotation validators is that they enable us to perform validation simply by adding one or more attributes on a model's property.
 
Blazor uses ASP.net Core validation attributes that are defined under System.ComponentModel.DataAnnotations namespace. There are many built-in data annotation attributes provided by .net core framework. You can also build your own data validation attribute (custom validation attribute).
 
Example
  1. namespace BlazorValidation.Data  
  2. {  
  3.     using System.ComponentModel.DataAnnotations;  
  4.     public class Employee  
  5.     {  
  6.         ...  
  7.         [Required]  
  8.         [StringLength(50)]  
  9.         public string Name { get; set; }  
  10.         ...  
  11.         ...  
  12.     }  
  13. }  
Blazor app supports the following built-in validation attributes.
 
 Attribute  Description
CreditCard   Validate property as per the credit card format
 CreditCard  Compare two model properties
 EmailAddress  Validate property as per the email format
 Phone  Validate property as per the phone number format
 Range  Validate the property value falls in specified range
 RegularExpression  Validate the property value match specified regular expression
 Required  Validate the property value is not null
 StringLength  Validate the property value must with in specified length limit
 Url  Validate property as per the url format
 Remote  Validate the property value by calling a specified server method
 
You can define the form in a Blazor app using "EditForm" component. The Blazor engine only validates the input model's property value that is defined in "EditForm" component. The Blazor provides a DataAnnotationsValidator compoment that tells the Blazor engine to validate a model using data annotation. Blazor provides two components: ValidationSummary and ValidationMessage to display a model validation error on screen.
 
The Blazor EditForm component provides OnValidSubmit event callback that is triggered when a form is successfully submitted without any validation error. OnInvalidSubmit event callback is triggered when a form has been submitted with a validation error.
 
Blazor also provides a set of built-in input components that receive and validate the user input. These components validate the content when they are changed or a form is submitted.
 
Follow the built-in component provided by Blazor.
 
 Component  Render as
 InputText  <input>
 InputCheckbox  <input type="checkbox">
 InputNumber  <input type="number">
 InputTextArea  <textarea>
 InputSelect  <select>
 InputDate  <input type="date">
 
Example

In the following example, Employee model has various properties and is decorated with a built-in validation data annotation attribute. 
  1. namespace BlazorValidation.Data  
  2. {  
  3.     using System.ComponentModel.DataAnnotations;  
  4.     public class EmployeeModel  
  5.     {  
  6.         public int Id { get; set; }  
  7.         [Required]  
  8.         [StringLength(50)]  
  9.         public string Name { get; set; }  
  10.         [Required]  
  11.         [EmailAddress]  
  12.         public string EmailAddress { get; set; }  
  13.         [Required]  
  14.         [Phone]  
  15.         public string PhoneNumer { get; set; }  
  16.         [Required]  
  17.         [CreditCard]  
  18.         public string CreditCardNumer { get; set; }  
  19.   
  20.     }  
  21. }  
Employee Razor page contains the EditForm component. Under the EditForm component, DataAnnotationsValidator and ValidationSummary component are defined. So, the Blazor engine will validate the inputs using data annotation and list down all form validation as a summary on the submit button click.
  1. @page "/editemployee"  
  2. @using BlazorValidation.Data;  
  3.   
  4. <h1>Add/Edit Employee</h1>  
  5.   
  6. <EditForm Model="@employee" OnValidSubmit="HandleValidSubmit">  
  7.     <DataAnnotationsValidator />  
  8.     <ValidationSummary />  
  9.     <div class="row content">  
  10.         <div class="col-md-2"><label for="Name">Name</label></div>  
  11.         <div class="col-md-3"><InputText id="name" @bind-Value="employee.Name" /></div>  
  12.     </div>  
  13.     <div class="row content">  
  14.         <div class="col-md-2"><label for="EmailAddress">Email</label></div>  
  15.         <div class="col-md-3"><InputText id="EmailAddress" @bind-Value="employee.EmailAddress" /></div>  
  16.     </div>  
  17.     <div class="row content">  
  18.         <div class="col-md-2"><label for="PhoneNumer">Phone</label></div>  
  19.         <div class="col-md-3"><InputText id="PhoneNumer" @bind-Value="employee.PhoneNumer" /></div>  
  20.     </div>  
  21.     <div class="row content">  
  22.         <div class="col-md-2"><label for="CreditCardNumer">Credit Card Numer</label></div>  
  23.         <div class="col-md-3"><InputText id="CreditCardNumer" @bind-Value="employee.CreditCardNumer" /></div>  
  24.     </div>  
  25.     <div class="row content">  
  26.         <button type="submit">Submit</button>  
  27.     </div>  
  28.   
  29. </EditForm>  
  30.   
  31. @code {  
  32.     EmployeeModel employee = new EmployeeModel();     
  33.     private void HandleValidSubmit()  
  34.     {  
  35.         Console.WriteLine("OnValidSubmit");  
  36.     }  
  37. }  
Output
 
 
Using ValidationMessage component, you can show a validation message for individual components. This component has a "for" attribute that is used to specify the field for the validation using lambda expression.
  1. @page "/editemployeeindividual"  
  2. @using BlazorValidation.Data;  
  3.   
  4. <h1>Add/Edit Employee</h1>  
  5.   
  6. <EditForm Model="@employee" OnValidSubmit="HandleValidSubmit">  
  7.     <DataAnnotationsValidator />  
  8.     <div class="row content">  
  9.         <div class="col-md-2"><label for="Name">Name</label></div>  
  10.         <div class="col-md-3"><InputText id="name" @bind-Value="employee.Name" /></div>  
  11.         <div class="col-md-5"><ValidationMessage For="@(() => employee.Name)" /> </div>  
  12.         </div>  
  13.     <div class="row content">  
  14.         <div class="col-md-2"><label for="EmailAddress">Email</label></div>  
  15.         <div class="col-md-3"><InputText id="EmailAddress" @bind-Value="employee.EmailAddress" /></div>  
  16.         <div class="col-md-5"><ValidationMessage For="@(() => employee.EmailAddress)" /> </div>  
  17.     </div>  
  18.     <div class="row content">  
  19.         <div class="col-md-2"><label for="PhoneNumer">Phone</label></div>  
  20.         <div class="col-md-3"><InputText id="PhoneNumer" @bind-Value="employee.PhoneNumer" /></div>  
  21.         <div class="col-md-5"><ValidationMessage For="@(() => employee.PhoneNumer)" /> </div>  
  22.     </div>  
  23.     <div class="row content">  
  24.         <div class="col-md-2"><label for="CreditCardNumer">Credit Card Numer</label></div>  
  25.         <div class="col-md-3"><InputText id="CreditCardNumer" @bind-Value="employee.CreditCardNumer" /></div>  
  26.         <div class="col-md-5"><ValidationMessage For="@(() => employee.CreditCardNumer)" /> </div>  
  27.     </div>  
  28.     <div class="row content">  
  29.         <button type="submit">Submit</button>  
  30.     </div>  
  31.   
  32. </EditForm>  
  33.   
  34. @code {  
  35.     EmployeeModel employee = new EmployeeModel();     
  36.     private void HandleValidSubmit()  
  37.     {  
  38.         Console.WriteLine("OnValidSubmit");  
  39.     }  
  40. }  
Output
 
 

Does Blazor support custom validation attribute?


Yes, Blazor also supports the custom validation attribute. The custom validation attribute must inherit from ValidationAttribute and needs to implement the overridable method "IsValid". This method returns ValidationResult and based on this the Blazor engine decides whether input value is valid or not.
 
Example
 
In the following example, custom validation attribute is created that only allows one(1). The "IsValid" method returns ValidationResult.Success if value is one; else it returns an error message.
  1. namespace BlazorValidation.Data  
  2. {  
  3.     using System;  
  4.     using System.ComponentModel.DataAnnotations;  
  5.     public class AllowOneValidationAttribute : ValidationAttribute  
  6.     {  
  7.         protected override ValidationResult IsValid(object value,  
  8.         ValidationContext validationContext)  
  9.         {  
  10.   
  11.             int valueInt = Convert.ToInt32(value);  
  12.             if (valueInt == 1)  
  13.             {  
  14.                 return ValidationResult.Success;  
  15.             }  
  16.   
  17.             return new ValidationResult("Error: only one is allowed in this property.",  
  18.                 new[] { validationContext.MemberName });  
  19.         }  
  20.     }  
  21. }  

Validate the complex property


The DataAnnotationsValidator component only validates top-level properties of the model. It does not validate collection or complex-type properties of model class. The Blazor provides ObjectGraphDataAnnotationsValidator to validate the entire model object including collection and complex-type properties.
 
This component is defined in Microsoft.AspNetCore.Blazor.DataAnnotations.Validation package and currently it is in an experimental stage. To use ObjectGraphDataAnnotationsValidator component, you need to install said package from NuGet.
  1. <EditForm Model="@model" OnValidSubmit="HandleValidSubmit">  
  2.     <ObjectGraphDataAnnotationsValidator />  
  3.     ...  
  4. </EditForm>  
All complex and collection type model properties must be decorated with ValidateComplexType attribute.
  1. namespace BlazorValidation.Data  
  2. {  
  3.     using System.ComponentModel.DataAnnotations;  
  4.     public class ComplexModel  
  5.     {  
  6.         [ValidateComplexType]  
  7.         public EmployeeModel Employee { get; set; }  
  8.     }  
  9. }  

Summary


Blazor supports data annotation validation. The data annotation validation attributes are easy to use and help us to reduce code size as well as re-usability. Using ObjectGraphDataAnnotationsValidator component, you can also validate complex type or collection type model, however it is in the experimental stage.