Forms and validation

Tip

This content is an excerpt from the eBook, Blazor for ASP NET Web Forms Developers for Azure, available on .NET Docs or as a free downloadable PDF that can be read offline.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover thumbnail.

The ASP.NET Web Forms framework includes a set of validation server controls that handle validating user input entered into a form (RequiredFieldValidator, CompareValidator, RangeValidator, and so on). The ASP.NET Web Forms framework also supports model binding and validating the model based on data annotations ([Required], [StringLength], [Range], and so on). The validation logic can be enforced both on the server and on the client using unobtrusive JavaScript-based validation. The ValidationSummary server control is used to display a summary of the validation errors to the user.

Blazor supports the sharing of validation logic between both the client and the server. ASP.NET provides pre-built JavaScript implementations of many common server validations. In many cases, the developer still has to write JavaScript to fully implement their app-specific validation logic. The same model types, data annotations, and validation logic can be used on both the server and client.

Blazor provides a set of input components. The input components handle binding field data to a model and validating the user input when the form is submitted.

Input component Rendered HTML element
InputCheckbox <input type="checkbox">
InputDate <input type="date">
InputNumber <input type="number">
InputSelect <select>
InputText <input>
InputTextArea <textarea>

The EditForm component wraps these input components and orchestrates the validation process through an EditContext. When creating an EditForm, you specify what model instance to bind to using the Model parameter. Validation is typically done using data annotations, and it's extensible. To enable data annotation-based validation, add the DataAnnotationsValidator component as a child of the EditForm. The EditForm component provides a convenient event for handling valid (OnValidSubmit) and invalid (OnInvalidSubmit) submissions. There's also a more generic OnSubmit event that lets you trigger and handle the validation yourself.

To display a validation error summary, use the ValidationSummary component. To display validation messages for a specific input field, use the ValidationMessage component, specifying a lambda expression for the For parameter that points to the appropriate model member.

The following model type defines several validation rules using data annotations:

using System;
using System.ComponentModel.DataAnnotations;

public class Starship
{
    [Required]
    [StringLength(16,
        ErrorMessage = "Identifier too long (16 character limit).")]
    public string Identifier { get; set; }

    public string Description { get; set; }

    [Required]
    public string Classification { get; set; }

    [Range(1, 100000,
        ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true",
        ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }
}

The following component demonstrates building a form in Blazor based on the Starship model type:

<h1>New Ship Entry Form</h1>

<EditForm Model="@starship" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <p>
        <label for="identifier">Identifier: </label>
        <InputText id="identifier" @bind-Value="starship.Identifier" />
        <ValidationMessage For="() => starship.Identifier" />
    </p>
    <p>
        <label for="description">Description (optional): </label>
        <InputTextArea id="description" @bind-Value="starship.Description" />
    </p>
    <p>
        <label for="classification">Primary Classification: </label>
        <InputSelect id="classification" @bind-Value="starship.Classification">
            <option value="">Select classification ...</option>
            <option value="Exploration">Exploration</option>
            <option value="Diplomacy">Diplomacy</option>
            <option value="Defense">Defense</option>
        </InputSelect>
        <ValidationMessage For="() => starship.Classification" />
    </p>
    <p>
        <label for="accommodation">Maximum Accommodation: </label>
        <InputNumber id="accommodation" @bind-Value="starship.MaximumAccommodation" />
        <ValidationMessage For="() => starship.MaximumAccommodation" />
    </p>
    <p>
        <label for="valid">Engineering Approval: </label>
        <InputCheckbox id="valid" @bind-Value="starship.IsValidatedDesign" />
        <ValidationMessage For="() => starship.IsValidatedDesign" />
    </p>
    <p>
        <label for="productionDate">Production Date: </label>
        <InputDate id="productionDate" @bind-Value="starship.ProductionDate" />
        <ValidationMessage For="() => starship.ProductionDate" />
    </p>

    <button type="submit">Submit</button>
</EditForm>

@code {
    private Starship starship = new Starship();

    private void HandleValidSubmit()
    {
        // Save the data
    }
}

After the form submission, the model-bound data hasn't been saved to any data store, like a database. In a Blazor WebAssembly app, the data must be sent to the server. For example, using an HTTP POST request. In a Blazor Server app, the data is already on the server, but it must be persisted. Handling data access in Blazor apps is the subject of the Dealing with data section.

Additional resources

For more information on forms and validation in Blazor apps, see the Blazor documentation.