Author : MD TAREQ HASSAN | Updated : 2020/08/16

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:

Built-in Form Components

Blazor has built-in form components

Ways to validate

Method -1 : <EditForm Model="@XxxModel" OnValidSubmit="@OnValidSubmission" OnInValidSubmit="@OnInValidSubmission">

Create.razor.cs

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)
	{
		// ... ... ...
	}
	
	protected void OnInValidSubmission(EditContext editContext)
	{
		// ... ... ...
	}
}

Create.razor

@page "/emails/create"
@inherits CreateBase

// ... ... ...

<EditForm Model="@CreateEmailModel" OnValidSubmit="@OnValidSubmission" OnInValidSubmit="@OnInValidSubmission">

    <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>

    // ... ... ...
	
</EditForm>

More: https://www.learmoreseekmore.com/2020/03/blazor-server-form-validation.html

Method - 2 : <EditForm EditContext="@_editContext" OnSubmit="@AddOrUpdate">

Create.razor.cs

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;

public class CreateBase: ComponentBase
{
	protected CreateEmailModel CreateEmailModel { get; set; }
	
    protected EditContext _editContext;
	
	// ... ... ...
	
	private void InitEditContext()
	{
		CreateEmailModel = new CreateEmailModel();
		_editContext = new EditContext(CreateEmailModel);
	}
	
	// Lifecycle callback
	protected override void OnInitialized()
	{
		InitEditContext();
	}

	protected void OnSubmit()
	{
		var isInvalidForm = !_editContext.Validate();

		if (isInvalidForm)
		{
			Debug.WriteLine($"Submitted form is not valid");
			return;
		}

		// Perfor operation i.e. _service.CreateEmailEntry(CreateEmailModel)
		
		
		// Reset edit context
		InitEditContext();
	}
	
	// ... ... ...
}

Create.razor

@page "/emails/create"
@inherits CreateBase

// ... ... ...

<EditForm EditContext="@_editContext" OnSubmit="@OnSubmit">

    <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>

    // ... ... ...
	
</EditForm>

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


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