Author : HASSAN MD TAREQ

Form validation in blazor

Forms and validation are supported (out-of-the-box) in Blazor using data annotations (the same component model data annotations that are used in MVC & Razor pages). To use validation we have to have model with data annotations and edit form defined in Blazor view.

Notes:

  • All of the input components, including EditForm, support arbitrary attributes. Any attribute that doesn’t match a component parameter is added to the rendered HTML element
  • Any attribute is rendered in HTML element
    • suppose we added xxx attribute in built-in component InputText : <InputText xxx="123" id="..." @bind-Value="@..." />
    • xxx will not match any parameter of InputText
    • xxx will be rendered as: <input xxx="123" id="..." class="valid">

Built-in Form Components

Blazor has built-in form components

  • A set of built-in input components are available to receive and validate user input
  • Inputs are validated when they’re changed and when a form is submitted
  • Example:
    • EditForm : Parent component for form. Supports form validation out of the box
    • InputText : An input component for editing String values
    • InputTextArea : A multiline input component for editing String values
    • etc.
  • Available form components : https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.forms

Basic EditForm Example

@page "/emails/create"
@inherits CreateBase

<h1>Create</h1>

<hr />

<EditForm Model="@CreateEmailModel" OnValidSubmit="@OnValidSubmission">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="form-group row">
        <label for="@nameof(CreateEmailModel.To)" class="col-1  text-right pr-1 my-auto">@nameof(CreateEmailModel.To):</label>
        <InputText id="@nameof(CreateEmailModel.To)" @bind-Value="@CreateEmailModel.To" class="col-5" />
        <ValidationMessage For="() => CreateEmailModel.To" class="col" />
    </div>

    <div class="form-group row">
        <label for="@nameof(CreateEmailModel.Cc)" class="col-1  text-right pr-1 my-auto">@nameof(CreateEmailModel.Cc):</label>
        <InputText id="@nameof(CreateEmailModel.Cc)" @bind-Value="@CreateEmailModel.Cc" class="col-5" />
        <ValidationMessage For="() => CreateEmailModel.Cc" class="col" />
    </div>

    <div class="form-group row">
        <label for="@nameof(CreateEmailModel.Bcc)" class="col-1  text-right pr-1 my-auto">@nameof(CreateEmailModel.Bcc):</label>
        <InputText id="@nameof(CreateEmailModel.Bcc)" @bind-Value="@CreateEmailModel.Bcc" class="col-5" />
        <ValidationMessage For="() => CreateEmailModel.Bcc" class="col" />
    </div>

    <div class="row">
        <div class="col-1">
        </div>
        <div class="col p-0 my-auto">
            <button type="submit" class="btn btn-success">Create</button>
        </div>
    </div>
</EditForm>

Create.razor.cs

using Blazor.Server.Models.InputModels;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;

public class CreateBase: ComponentBase
{
	protected CreateEmailModel CreateEmailModel { get; set; }


	protected override void OnInitialized()
	{
		CreateEmailModel = new CreateEmailModel();
	}

	protected void OnValidSubmission(EditContext editContext)
	{
		// ... ... ...
	}
}

CreateEmailModel.cs

using System.ComponentModel.DataAnnotations;
public class CreateEmailModel
{
	[Required]
	[StringLength(50)]
	public string To { get; set; }

	public string Cc { get; set; }

	public string Bcc { get; set; }
}

Form Submission

  • There are three events on an EditForm related to form submission:
    • OnValidSubmit
    • OnInvalidSubmit
    • OnSubmit
  • OnValidSubmit + OnInvalidSubmit” and “OnSubmit” are mutually exclusive, that means use either [OnValidSubmit and/or OnInvalidSubmit] or [OnSubmit]
  • From submission events pass EditContext as a parameter
    • EditContext can be used to check form input
    • Example: bool formIsValid = editContext.Validate();


Using C# code in the same file for simplicity, use code behind approach as best practice

OnValidSubmit + OnInvalidSubmit

<EditForm Model="" OnValidSubmit="@OnValidSubmission" OnInvalidSubmit="@OnInvalidSubmission">
  <!-- ... ... ...  -->
</EditForm>

@code {

  void OnValidSubmission(EditContext editContext)
  {
    // ... ... ...
  }

  void OnInvalidSubmission(EditContext editContext)
  {
    // ... ... ...
  }
}

OnSubmit

<EditForm Model="" OnValidSubmit="@OnValidSubmission" OnInvalidSubmit="@OnInvalidSubmission">
  <!-- ... ... ...  -->
</EditForm>

@code {

  void FormSubmitted(EditContext editContext)
  {
    bool formIsValid = editContext.Validate();
	
    // ... ... ...
  }

Validating a Form

Prerequisite: Scaffolding CRUD in blazor server