Filter by title
Document Options

There are multiple versions of this document. Pick the options that suit you best.

Blazor UI Library:

Blazor UI: Forms & Validation

ABP Blazor UI built on top of MudBlazor uses MudBlazor's built-in form components and validation infrastructure. MudBlazor accepts a ValidationAttribute (e.g. [Required], [EmailAddress] from ASP.NET Core's DataAnnotations) on the input's Validation parameter, plus custom Func<T, string> / Func<T, IEnumerable<string>> delegates. FluentValidation can be plugged in the same way.

Sample

The most common pattern is wrapping inputs in a <MudForm> and binding the form's validation state through IsValid:

Standard MudBlazor and ABP usings (@using MudBlazor, @using Volo.Abp.MudBlazorUI, etc.) come from the project's _Imports.razor. The example below only adds the additional usings needed for validation.

@using System.ComponentModel.DataAnnotations

<MudForm @ref="_form" @bind-IsValid="@_isValid" Model="@_model">
    <MudStack Spacing="3">
        <MudTextField @bind-Value="_model.Name"
                      Label="Name"
                      Required="true"
                      RequiredError="Please enter the name." />

        <MudTextField @bind-Value="_model.Email"
                      Label="Email"
                      Required="true"
                      Validation="@(new EmailAddressAttribute() { ErrorMessage = "Enter a valid email." })" />

        <MudButton OnClick="@SubmitAsync"
                   Disabled="@(!_isValid)"
                   Variant="Variant.Filled"
                   Color="Color.Primary">
            Submit
        </MudButton>
    </MudStack>
</MudForm>

@code {
    private MudForm _form;
    private bool _isValid;
    private SampleModel _model = new();

    private async Task SubmitAsync()
    {
        await _form.Validate();
        if (_isValid)
        {
            // ...
        }
    }

    public class SampleModel
    {
        [Required]
        public string Name { get; set; }

        [Required, EmailAddress]
        public string Email { get; set; }
    }
}

Inputs Used in CRUD Pages

ABP's MudBlazor CRUD pages (see AbpMudCrudPageBase) use a <MudDialog> containing a <MudForm> and standard MudBlazor inputs:

  • <MudTextField> / <MudTextField Lines="N"> for text and multi-line text
  • <MudSelect> / <MudSelectItem> for dropdowns
  • <MudCheckBox> for booleans
  • <MudDatePicker> / <MudTimePicker> for date and time
  • <MudNumericField> for numbers

AbpMudCrudPageBase.CreateEntityAsync and UpdateEntityAsync validate the form for you (CreateFormRef.Validate() / EditFormRef.Validate()) and only call the corresponding hook when the form is valid. To inject custom logic before the application service call, override OnCreatingEntityAsync / OnUpdatingEntityAsync (do not re-validate inside the override):

protected override Task OnCreatingEntityAsync()
{
    // mutate NewEntity here if needed
    return base.OnCreatingEntityAsync();
}

Check the MudBlazor documentation for the full list of validation modes and the MudBlazor inputs reference.

By default a MudFocusTrap inside <MudDialog> focuses the first tabbable child element after the dialog opens. When the dialog contains a <MudTabs> as the first child, that "first tabbable element" is the tab button — not the first input on the active tab — so the user has to click into the field manually.

For dialogs that contain a <MudTabs>, use this three-part setup to focus the intended input automatically:

<MudDialog DefaultFocus="DefaultFocus.None" @ref="_createDialog" Options="@CreateDialogOptions">
    <DialogContent>
        <MudForm @ref="@CreateFormRef" Model="@NewEntity">
            <MudTabs @bind-ActivePanelIndex="@_createTabIndex" KeepPanelsAlive="true">
                <MudTabPanel Text="@L["UserInformations"]">
                    <MudTextField @bind-Value="@NewEntity.UserName"
                                  Label="@L["UserName"]"
                                  AutoFocus="true"
                                  Required="true" />
                    ...
                </MudTabPanel>
                ...
  • DefaultFocus="DefaultFocus.None" on the <MudDialog> disables the focus trap's automatic focus so it doesn't grab the tab button.
  • KeepPanelsAlive="true" on the <MudTabs> mounts every tab panel up front, so the first input's firstRender happens at dialog-open time (otherwise inactive panels are mounted later, and AutoFocus runs after the dialog is already visible).
  • AutoFocus="true" on the first input asks MudBlazor to focus that field on its first render.

DialogOptions.DefaultFocus is ignored for inline dialogs (<MudDialog @ref> + ShowAsync()), so always set DefaultFocus directly on the <MudDialog> element.

For a dialog without <MudTabs> (first child is the input), DefaultFocus="DefaultFocus.FirstChild" (the MudBlazor default) is enough and you don't need AutoFocus.

Contributors


Last updated: May 21, 2026 Edit this page on GitHub

Was this page helpful?

Please make a selection.

To help us improve, please share your reason for the negative feedback in the field below.

Please enter a note.

Thank you for your valuable feedback!

Please note that although we cannot respond to feedback, our team will use your comments to improve the experience.

ABP Community Talks
ABP AI Coding Agent for Every .NET Developer
15 Oct, 17:00
Online
Register Now
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.