You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -5,7 +5,7 @@ description: Learn how to use validation in Blazor forms.
5
5
monikerRange: '>= aspnetcore-3.1'
6
6
ms.author: wpickett
7
7
ms.custom: mvc
8
-
ms.date: 11/11/2025
8
+
ms.date: 11/25/2025
9
9
uid: blazor/forms/validation
10
10
---
11
11
# ASP.NET Core Blazor forms validation
@@ -1572,48 +1572,6 @@ The <xref:System.ComponentModel.DataAnnotations.CompareAttribute> doesn't work w
1572
1572
1573
1573
:::moniker range=">= aspnetcore-10.0"
1574
1574
1575
-
## Use validation models from a different assembly
1576
-
1577
-
For model validation defined in a different assembly, such as a library or the `.Client` project of a Blazor Web App:
1578
-
1579
-
* If the library is a plain class library (it isn't based on the `Microsoft.NET.Sdk.Web` or `Microsoft.NET.Sdk.Razor` SDKs), add a package reference to the library for the [`Microsoft.Extensions.Validation` NuGet package](https://www.nuget.org/packages/Microsoft.Extensions.Validation).
1580
-
* Create a method in the library or `.Client` project that receives an <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> instance as an argument and calls <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A> on it.
1581
-
* In the app, call both the method and <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A>.
1582
-
1583
-
The preceding approach results in validation of the types from both assemblies.
1584
-
1585
-
In the following example, the `AddValidationForTypesInClient` method is created for the `.Client` project of a Blazor Web App for validation using types defined in the `.Client` project.
1586
-
1587
-
`ServiceCollectionExtensions.cs` (in the `.Client` project):
In the server project's `Program` file, add the namespace and call the `.Client` project's service collection extension method (`AddValidationForTypesInClient`) and <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A>:
1603
-
1604
-
```csharp
1605
-
usingBlazorSample.Client.Extensions;
1606
-
1607
-
...
1608
-
1609
-
builder.Services.AddValidationForTypesInClient();
1610
-
builder.Services.AddValidation();
1611
-
```
1612
-
1613
-
:::moniker-end
1614
-
1615
-
:::moniker range=">= aspnetcore-10.0"
1616
-
1617
1575
## Nested objects and collection types
1618
1576
1619
1577
Blazor form validation includes support for validating properties of nested objects and collection items with the built-in <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator>.
@@ -1643,6 +1601,8 @@ In the following `Order` class, the `[ValidatableType]` attribute is required on
1643
1601
`Order.cs`:
1644
1602
1645
1603
```csharp
1604
+
usingSystem.ComponentModel.DataAnnotations;
1605
+
1646
1606
[ValidatableType]
1647
1607
publicclassOrder
1648
1608
{
@@ -1691,6 +1651,8 @@ In the following `OrderPage` component, the <xref:Microsoft.AspNetCore.Component
1691
1651
1692
1652
The requirement to declare the model types outside of Razor components (`.razor` files) is due to the fact that both the new validation feature and the Razor compiler itself are using a source generator. Currently, output of one source generator can't be used as an input for another source generator.
1693
1653
1654
+
For guidance on using validation models from a different assembly, see the [Use validation models from a different assembly](#use-validation-models-from-a-different-assembly) section.
1655
+
1694
1656
:::moniker-end
1695
1657
1696
1658
:::moniker range="< aspnetcore-10.0"
@@ -1750,6 +1712,106 @@ public class ShipDescription
1750
1712
1751
1713
:::moniker-end
1752
1714
1715
+
:::moniker range=">= aspnetcore-10.0"
1716
+
1717
+
## Use validation models from a different assembly
1718
+
1719
+
<!-- UPDATE 11.0 - The first list item changes when the content
1720
+
is updated for plain class libs upon
1721
+
experimental status dropping at 11.0 -->
1722
+
1723
+
For model validation defined in a different assembly, such as a library or the `.Client` project of a Blazor Web App:
1724
+
1725
+
* If the library is a plain class library (it isn't based on the `Microsoft.NET.Sdk.Web` or `Microsoft.NET.Sdk.Razor` SDKs), add a package reference to the library for the [`Microsoft.Extensions.Validation` NuGet package](https://www.nuget.org/packages/Microsoft.Extensions.Validation). Additional steps are required for plain class libraries, which are described later in this section.
1726
+
* Create a method in the library or `.Client` project that receives an <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> instance as an argument and calls <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A> on it.
1727
+
* In the app, call both the method and <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A>.
1728
+
1729
+
The preceding approach results in validation of the types from both assemblies.
1730
+
1731
+
In the following example, the `AddValidationForTypesInClient` method is created for the `.Client` project of a Blazor Web App for validation using types defined in the `.Client` project.
1732
+
1733
+
`ServiceCollectionExtensions.cs` (in the `.Client` project):
In the server project's `Program` file, add the namespace and call the `.Client` project's service collection extension method (`AddValidationForTypesInClient`) and <xref:Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation%2A>:
1749
+
1750
+
```csharp
1751
+
usingBlazorSample.Client.Extensions;
1752
+
1753
+
...
1754
+
1755
+
builder.Services.AddValidationForTypesInClient();
1756
+
builder.Services.AddValidation();
1757
+
```
1758
+
1759
+
<!-- UPDATE 11.0 - The following changes when the content
1760
+
is updated for plain class libs upon
1761
+
experimental status dropping at 11.0 -->
1762
+
1763
+
The new attributes from the `Microsoft.Extensions.Validation` package (<xref:Microsoft.Extensions.Validation.ValidatableTypeAttribute> and <xref:Microsoft.Extensions.Validation.SkipValidationAttribute>) are published as *experimental* in .NET 10. The package is intended to provide a new shared infrastructure for validation features across frameworks, and publishing experimental types provides greater flexibility for the final design of the public API for better support in consuming frameworks.
1764
+
1765
+
In Blazor apps, types are made available via a generated embedded attribute. If a web app project that uses the `Microsoft.NET.Sdk.Web` SDK (`<Project Sdk="Microsoft.NET.Sdk.Web">`) or an RCL that uses the `Microsoft.NET.Sdk.Razor` SDK (`<Project Sdk="Microsoft.NET.Sdk.Razor">`) contains Razor components (`.razor`), the framework automatically generates an internal attribute inside the project (`Microsoft.Extensions.Validation.Embedded.ValidatableType`, `Microsoft.Extensions.Validation.Embedded.SkipValidation`). These types are interchangeable with the actual attributes and not marked experimental. In the majority of cases, developers use the `[ValidatableType]`/`[SkipValidation]` attributes on their classes without concern over their source.
1766
+
1767
+
However, the preceding approach isn't viable in plain class libraries that use the `Microsoft.NET.Sdk` SDK (`<Project Sdk="Microsoft.NET.Sdk">`). Using the types in a plain class library results in an code analysis warning:
1768
+
1769
+
> :::no-loc text="ASP0029: 'Microsoft.Extensions.Validation.ValidatableTypeAttribute' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.":::
1770
+
1771
+
The warning can be suppressed using any of the following approaches:
1772
+
1773
+
* A `<NoWarn>` property in the project file:
1774
+
1775
+
```xml
1776
+
<PropertyGroup>
1777
+
<NoWarn>$(NoWarn);ASP0029</NoWarn>
1778
+
</PropertyGroup>
1779
+
```
1780
+
1781
+
* A [`pragma` directive](/cpp/preprocessor/pragma-directives-and-the-pragma-keyword) where the attribute is used:
1782
+
1783
+
```csharp
1784
+
#pragmawarningdisable ASP0029
1785
+
[Microsoft.Extensions.Validation.ValidatableType]
1786
+
#pragmawarningrestore ASP0029
1787
+
```
1788
+
1789
+
* An [EditorConfig file (`.editorconfig`)](/visualstudio/ide/create-portable-custom-editor-options) rule:
1790
+
1791
+
```
1792
+
dotnet_diagnostic.ASP0029.severity = none
1793
+
```
1794
+
1795
+
If suppressing the warning isn't acceptable, manually create the embedded attribute in the library that the Web and Razor SDKs generate automatically.
Use the exact namespace (`Microsoft.Extensions.Validation.Embedded`) and class name (`ValidatableTypeAttribute`) in order for the validation source generator to detect and use the type. You can declare a global `using` statement for the namespace, either with a `global using Microsoft.Extensions.Validation.Embedded;` statement or with a `<Using Include="Microsoft.Extensions.Validation.Embedded" />` item in the library's project file.
1810
+
1811
+
Whichever approach is adopted, denote the presence of the workaround for a future update to your code. Framework updates to ease the adoption of validation types in plain class libraries are planned for .NET 11 (November, 2026).
1812
+
1813
+
:::moniker-end
1814
+
1753
1815
## Enable the submit button based on form validation
1754
1816
1755
1817
To enable and disable the submit button based on form validation, the following example:
0 commit comments