AspNetCore.Docs/aspnetcore/blazor/forms-validation.md

203 lines
8.8 KiB
Markdown
Raw Normal View History

---
title: ASP.NET Core Blazor forms and validation
author: guardrex
2019-04-16 04:39:32 +08:00
description: Learn how to use forms and field validation scenarios in Blazor.
monikerRange: '>= aspnetcore-3.0'
ms.author: riande
ms.custom: mvc
ms.date: 09/23/2019
2019-04-16 04:39:32 +08:00
uid: blazor/forms-validation
---
# ASP.NET Core Blazor forms and validation
By [Daniel Roth](https://github.com/danroth27) and [Luke Latham](https://github.com/guardrex)
2019-04-16 04:39:32 +08:00
Forms and validation are supported in Blazor using [data annotations](xref:mvc/models/validation).
The following `ExampleModel` type defines validation logic using data annotations:
```csharp
using System.ComponentModel.DataAnnotations;
public class ExampleModel
{
[Required]
[StringLength(10, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
}
```
2019-07-03 06:14:03 +08:00
A form is defined using the `EditForm` component. The following form demonstrates typical elements, components, and Razor code:
```csharp
<EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText id="name" @bind-Value="@exampleModel.Name" />
<button type="submit">Submit</button>
</EditForm>
@code {
private ExampleModel exampleModel = new ExampleModel();
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
```
2019-07-03 06:14:03 +08:00
* The form validates user input in the `name` field using the validation defined in the `ExampleModel` type. The model is created in the component's `@code` block and held in a private field (`exampleModel`). The field is assigned to the `Model` attribute of the `<EditForm>` element.
* The `DataAnnotationsValidator` component attaches validation support using data annotations.
* The `ValidationSummary` component summarizes validation messages.
* `HandleValidSubmit` is triggered when the form successfully submits (passes validation).
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. Available input components are shown in the following table.
2019-07-03 06:14:03 +08:00
| Input component | Rendered as&hellip; |
| --------------- | ------------------------- |
| `InputText` | `<input>` |
| `InputTextArea` | `<textarea>` |
| `InputSelect` | `<select>` |
| `InputNumber` | `<input type="number">` |
| `InputCheckbox` | `<input type="checkbox">` |
| `InputDate` | `<input type="date">` |
2019-07-03 06:14:03 +08:00
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.
2019-07-03 06:14:03 +08:00
Input components provide default behavior for validating on edit and changing their CSS class to reflect the field state. Some components include useful parsing logic. For example, `InputDate` and `InputNumber` handle unparseable values gracefully by registering them as validation errors. Types that can accept null values also support nullability of the target field (for example, `int?`).
2019-07-03 06:14:03 +08:00
The following `Starship` type defines validation logic using a larger set of properties and data annotations than the earlier `ExampleModel`:
```csharp
using System;
using System.ComponentModel.DataAnnotations;
public class Starship
{
[Required]
2019-07-03 06:14:03 +08:00
[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",
2019-07-03 06:14:03 +08:00
ErrorMessage = "This form disallows unapproved ships.")]
public bool IsValidatedDesign { get; set; }
[Required]
public DateTime ProductionDate { get; set; }
}
```
2019-07-03 06:14:03 +08:00
In the preceding example, `Description` is optional because no data annotations are present.
The following form validates user input using the validation defined in the `Starship` model:
```cshtml
@page "/FormsValidation"
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm Model="@starship" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label for="identifier">Identifier: </label>
2019-07-03 06:14:03 +08:00
<InputText id="identifier" @bind-Value="starship.Identifier" />
</p>
<p>
<label for="description">Description (optional): </label>
2019-08-15 07:40:19 +08:00
<InputTextArea id="description" @bind-Value="starship.Description" />
</p>
<p>
<label for="classification">Primary Classification: </label>
2019-07-03 06:14:03 +08:00
<InputSelect id="classification" @bind-Value="starship.Classification">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
2019-07-03 06:14:03 +08:00
<option value="Defense">Defense</option>
</InputSelect>
</p>
<p>
<label for="accommodation">Maximum Accommodation: </label>
<InputNumber id="accommodation"
2019-07-03 06:14:03 +08:00
@bind-Value="starship.MaximumAccommodation" />
</p>
<p>
<label for="valid">Engineering Approval: </label>
2019-07-03 06:14:03 +08:00
<InputCheckbox id="valid" @bind-Value="starship.IsValidatedDesign" />
</p>
<p>
<label for="productionDate">Production Date: </label>
2019-08-15 07:40:19 +08:00
<InputDate id="productionDate" @bind-Value="starship.ProductionDate" />
</p>
<button type="submit">Submit</button>
<p>
<a href="http://www.startrek.com/">Star Trek</a>,
&copy;1966-2019 CBS Studios, Inc. and
<a href="https://www.paramount.com">Paramount Pictures</a>
</p>
</EditForm>
@code {
private Starship starship = new Starship();
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
```
2019-07-03 06:14:03 +08:00
The `EditForm` creates an `EditContext` as a [cascading value](xref:blazor/components#cascading-values-and-parameters) that tracks metadata about the edit process, including which fields have been modified and the current validation messages. The `EditForm` also provides convenient events for valid and invalid submits (`OnValidSubmit`, `OnInvalidSubmit`). Alternatively, use `OnSubmit` to trigger the validation and check field values with custom validation code.
## InputText based on the input event
Use the `InputText` component to create a custom component that uses the `input` event instead of the `change` event.
Create a component with the following markup, and use the component just as `InputText` is used:
```cshtml
@inherits InputText
<input
@attributes="AdditionalAttributes"
class="@CssClass"
value="@CurrentValue"
@oninput="EventCallback.Factory.CreateBinder<string>(
this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
```
## Validation support
The `DataAnnotationsValidator` component attaches validation support using data annotations to the cascaded `EditContext`. Enabling support for validation using data annotations requires this explicit gesture. To use a different validation system than data annotations, replace the `DataAnnotationsValidator` with a custom implementation. The ASP.NET Core implementation is available for inspection in the reference source: [DataAnnotationsValidator](https://github.com/aspnet/AspNetCore/blob/master/src/Components/Forms/src/DataAnnotationsValidator.cs)/[AddDataAnnotationsValidation](https://github.com/aspnet/AspNetCore/blob/master/src/Components/Forms/src/EditContextDataAnnotationsExtensions.cs).
2019-07-03 06:14:03 +08:00
The `ValidationSummary` component summarizes all validation messages, which is similar to the [Validation Summary Tag Helper](xref:mvc/views/working-with-forms#the-validation-summary-tag-helper).
2019-07-03 06:14:03 +08:00
The `ValidationMessage` component displays validation messages for a specific field, which is similar to the [Validation Message Tag Helper](xref:mvc/views/working-with-forms#the-validation-message-tag-helper). Specify the field for validation with the `For` attribute and a lambda expression naming the model property:
```cshtml
<ValidationMessage For="@(() => starship.MaximumAccommodation)" />
```
2019-07-03 06:14:03 +08:00
The `ValidationMessage` and `ValidationSummary` components support arbitrary attributes. Any attribute that doesn't match a component parameter is added to the generated `<div>` or `<ul>` element.
### Validation of complex or collection type properties
Validation attributes applied to the properties of a model validate when the form is submitted. However, the properties of collections or complex data types of a model aren't validated on form submission. To honor the nested validation attributes in this scenario, use a custom validation component. For an example, see the [Blazor Validation sample in the aspnet/samples GitHub repository](https://github.com/aspnet/samples/tree/master/samples/aspnetcore/blazor/Validation).