Skip to content

Commit 09fd880

Browse files
authored
Improve custom form validation coverage (#34790)
1 parent 26f2328 commit 09fd880

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

aspnetcore/blazor/forms/validation.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ In the following component, the `HandleValidationRequested` handler method clear
132132
The <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component attaches data annotations validation to a cascaded <xref:Microsoft.AspNetCore.Components.Forms.EditContext>. Enabling data annotations validation requires the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component. To use a different validation system than data annotations, use a custom implementation instead of the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component. The framework implementations for <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> are available for inspection in the reference source:
133133

134134
* [`DataAnnotationsValidator`](https://github.com/dotnet/AspNetCore/blob/main/src/Components/Forms/src/DataAnnotationsValidator.cs)
135-
* [`AddDataAnnotationsValidation`](https://github.com/dotnet/AspNetCore/blob/main/src/Components/Forms/src/EditContextDataAnnotationsExtensions.cs).
135+
* [`AddDataAnnotationsValidation`](https://github.com/dotnet/AspNetCore/blob/main/src/Components/Forms/src/EditContextDataAnnotationsExtensions.cs)
136+
137+
If you need to enable data annotations validation support for an <xref:Microsoft.AspNetCore.Components.Forms.EditContext> in code, call <xref:Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.EnableDataAnnotationsValidation%2A> with an injected <xref:System.IServiceProvider> (`@inject IServiceProvider ServiceProvider`) on the <xref:Microsoft.AspNetCore.Components.Forms.EditContext>. For an advanced example, see the [`NotifyPropertyChangedValidationComponent` component in the ASP.NET Core Blazor framework's `BasicTestApp` (`dotnet/aspnetcore` GitHub repository)](https://github.com/dotnet/aspnetcore/blob/main/src/Components/test/testassets/BasicTestApp/FormsTest/NotifyPropertyChangedValidationComponent.razor). In a production version of the example, replace the `new TestServiceProvider()` argument for the service provider with an injected <xref:System.IServiceProvider>.
136138

137139
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
138140

@@ -141,6 +143,68 @@ Blazor performs two types of validation:
141143
* *Field validation* is performed when the user tabs out of a field. During field validation, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component associates all reported validation results with the field.
142144
* *Model validation* is performed when the user submits the form. During model validation, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component attempts to determine the field based on the member name that the validation result reports. Validation results that aren't associated with an individual member are associated with the model rather than a field.
143145

146+
In custom validation scenarios:
147+
148+
* Validation manages a <xref:Microsoft.AspNetCore.Components.Forms.ValidationMessageStore> for a form's <xref:Microsoft.AspNetCore.Components.Forms.EditContext>.
149+
* The <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component is used to attach validation support to forms based on [validation attributes (data annotations)](xref:mvc/models/validation#validation-attributes).
150+
151+
There are two general approaches for achieving custom validation, which are described in the next two sections of this article:
152+
153+
* [Manual validation using the `OnValidationRequested` event](#manual-validation-using-the-onvalidationrequested-event): Manually validate a form's fields with data annotations validation and custom code for field checks when validation is requested via an event handler assigned to the <xref:Microsoft.AspNetCore.Components.Forms.EditContext.OnValidationRequested%2A> event.
154+
* [Validator components](#validator-components): One or more custom validator components can be used to process validation for different forms on the same page or the same form at different steps of form processing (for example, client validation followed by server validation).
155+
156+
## Manual validation using the `OnValidationRequested` event
157+
158+
You can manually validate a form with a custom event handler assigned to the <xref:Microsoft.AspNetCore.Components.Forms.EditContext.OnValidationRequested%2A?displayProperty=nameWithType> event to manage a <xref:Microsoft.AspNetCore.Components.Forms.ValidationMessageStore>.
159+
160+
The Blazor framework provides the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component to attach additional validation support to forms based on [validation attributes (data annotations)](xref:mvc/models/validation#validation-attributes).
161+
162+
Recalling the earlier `Starship8` component example, the `HandleValidationRequested` method is assigned to <xref:Microsoft.AspNetCore.Components.Forms.EditContext.OnValidationRequested%2A>, where you can perform manual validation in C# code. A few changes demonstrate combining the existing manual validation with data annotations validation via a <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> and a validation attribute applied to the `Holodeck` model.
163+
164+
Reference the <xref:System.ComponentModel.DataAnnotations?displayProperty=fullName> namespace in the component's Razor directives at the top of the component definition file:
165+
166+
```razor
167+
@using System.ComponentModel.DataAnnotations
168+
```
169+
170+
Add an `Id` property to the `Holodeck` model with a validation attribute to limit the string's length to six characters:
171+
172+
```csharp
173+
[StringLength(6)]
174+
public string? Id { get; set; }
175+
```
176+
177+
Add a <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component (`<DataAnnotationsValidator />`) to the form. Typically, the component is placed immediately under the `<EditForm>` tag, but you can place it anywhere in the form:
178+
179+
```razor
180+
<DataAnnotationsValidator />
181+
```
182+
183+
Change the form's submit behavior in the `<EditForm>` tag from <xref:Microsoft.AspNetCore.Components.Forms.EditForm.OnSubmit> to <xref:Microsoft.AspNetCore.Components.Forms.EditForm.OnValidSubmit>, which ensures that the form is valid before executing the assigned event handler method:
184+
185+
```diff
186+
- OnSubmit="Submit"
187+
+ OnValidSubmit="Submit"
188+
```
189+
190+
In the `<EditForm>`, add a field for the `Id` property:
191+
192+
```razor
193+
<div>
194+
<label>
195+
<InputText @bind-Value="Model!.Id" />
196+
ID (6 characters max)
197+
</label>
198+
<ValidationMessage For="() => Model!.Id" />
199+
</div>
200+
```
201+
202+
After making the preceding changes, the form's behavior matches the following specification:
203+
204+
* The data annotations validation on the `Id` property doesn't trigger a validation failure when the `Id` field merely loses focus. The validation executes when the user selects the **`Update`** button.
205+
* Any manual validation that you want to perform in the `HandleValidationRequested` method assigned to the form's <xref:Microsoft.AspNetCore.Components.Forms.EditContext.OnValidationRequested%2A> event executes when the user selects the form's **`Update`** button. In the existing code of the `Starship8` component example, the user must select either or both of the checkboxes to validate the form.
206+
* The form doesn't process the `Submit` method until both the data annotations and manual validation pass.
207+
144208
## Validator components
145209

146210
Validator components support form validation by managing a <xref:Microsoft.AspNetCore.Components.Forms.ValidationMessageStore> for a form's <xref:Microsoft.AspNetCore.Components.Forms.EditContext>.

0 commit comments

Comments
 (0)