Skip to content

Commit f1e5859

Browse files
authored
Merge pull request #36403 from dotnet/main
2 parents 768feea + 5306b42 commit f1e5859

File tree

4 files changed

+157
-45
lines changed

4 files changed

+157
-45
lines changed

.github/workflows/blazor-issue-processing.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,19 @@ jobs:
2525
repo: context.repo.repo,
2626
body: `### 🦃 ***Happy Thanksgiving!*** 🍽️
2727
28-
*Stand-by!* A green dinosaur 🦖 will be along shortly to assist.`
28+
This issue has been marked for triage on the Blazor Docs GitHub project, and I'll respond after the Thanksgiving holiday during the first week of December.
29+
30+
We only work on documentation on this repo. If you need product support, close this issue and seek assistance through one or more of the following support channels:
31+
32+
* [Stack Overflow (tagged: 'blazor')](https://stackoverflow.com/questions/tagged/blazor)
33+
* [General ASP.NET Core Slack Team](https://aspnetcore.slack.com/join/shared_invite/zt-1mv5487zb-EOZxJ1iqb0A0ajowEbxByQ#/shared-invite/email)
34+
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)
35+
36+
If you think that you found a potential bug in the framework or have product feedback, close this issue and open a new issue for the ASP.NET Core product unit at [dotnet/aspnetcore issues](https://github.com/dotnet/aspnetcore/issues). Bug reports require a clear explanation of the problem, usually including a minimal repro project placed on GitHub for the product unit engineers to download and run. If you determine with the product unit that it isn't a bug but merely requires documentation, please re-open this docs issue and place a cross-link to your engineering issue discussion.
37+
38+
For problems or feedback on Visual Studio, close this issue and use the [**Report a Problem**](https://docs.microsoft.com/visualstudio/ide/how-to-report-a-problem-with-visual-studio) or [**Suggest a Feature**](https://docs.microsoft.com/visualstudio/ide/suggest-a-feature) processes from within VS, which open internal issues for the VS product unit. For more information, see [Visual Studio Feedback](https://developercommunity.visualstudio.com/home).
39+
40+
For problems with Visual Studio Code, close this issue and ask for support on community support forums. For bug reports and product feedback, open an issue on the [microsoft/vscode GitHub repo](https://github.com/microsoft/vscode/issues).`
2941
})
3042
await github.rest.issues.addLabels({
3143
issue_number: context.issue.number,

aspnetcore/blazor/forms/validation.md

Lines changed: 105 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn how to use validation in Blazor forms.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: wpickett
77
ms.custom: mvc
8-
ms.date: 11/11/2025
8+
ms.date: 11/25/2025
99
uid: blazor/forms/validation
1010
---
1111
# ASP.NET Core Blazor forms validation
@@ -1572,48 +1572,6 @@ The <xref:System.ComponentModel.DataAnnotations.CompareAttribute> doesn't work w
15721572

15731573
:::moniker range=">= aspnetcore-10.0"
15741574

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):
1588-
1589-
```csharp
1590-
namespace BlazorSample.Client.Extensions;
1591-
1592-
public static class ServiceCollectionExtensions
1593-
{
1594-
public static IServiceCollection AddValidationForTypesInClient(
1595-
this IServiceCollection collection)
1596-
{
1597-
return collection.AddValidation();
1598-
}
1599-
}
1600-
```
1601-
1602-
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-
using BlazorSample.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-
16171575
## Nested objects and collection types
16181576

16191577
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
16431601
`Order.cs`:
16441602

16451603
```csharp
1604+
using System.ComponentModel.DataAnnotations;
1605+
16461606
[ValidatableType]
16471607
public class Order
16481608
{
@@ -1691,6 +1651,8 @@ In the following `OrderPage` component, the <xref:Microsoft.AspNetCore.Component
16911651

16921652
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.
16931653

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+
16941656
:::moniker-end
16951657

16961658
:::moniker range="< aspnetcore-10.0"
@@ -1750,6 +1712,106 @@ public class ShipDescription
17501712

17511713
:::moniker-end
17521714

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):
1734+
1735+
```csharp
1736+
namespace BlazorSample.Client.Extensions;
1737+
1738+
public static class ServiceCollectionExtensions
1739+
{
1740+
public static IServiceCollection AddValidationForTypesInClient(
1741+
this IServiceCollection collection)
1742+
{
1743+
return collection.AddValidation();
1744+
}
1745+
}
1746+
```
1747+
1748+
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+
using BlazorSample.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+
#pragma warning disable ASP0029
1785+
[Microsoft.Extensions.Validation.ValidatableType]
1786+
#pragma warning restore 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.
1796+
1797+
`ValidatableTypeAttribute.cs`:
1798+
1799+
```csharp
1800+
namespace Microsoft.Extensions.Validation.Embedded
1801+
{
1802+
[AttributeUsage(AttributeTargets.Class)]
1803+
internal sealed class ValidatableTypeAttribute : Attribute
1804+
{
1805+
}
1806+
}
1807+
```
1808+
1809+
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+
17531815
## Enable the submit button based on form validation
17541816

17551817
To enable and disable the submit button based on form validation, the following example:

aspnetcore/blazor/fundamentals/environments.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,50 @@ On the client for a Blazor Web App, the environment is determined from the serve
3838
<!--Blazor-WebAssembly:{"environmentName":"Development", ...}-->
3939
```
4040

41-
For a standalone Blazor WebAssembly app, set the environment with the `<WasmApplicationEnvironmentName>` property in the app's project file (`.csproj`). The following example sets the `Staging` environment:
41+
For a standalone Blazor WebAssembly app, set the environment with the `<WasmApplicationEnvironmentName>` MSBuild property in the app's project file (`.csproj`). The following example sets the `Staging` environment:
4242

4343
```xml
4444
<WasmApplicationEnvironmentName>Staging</WasmApplicationEnvironmentName>
4545
```
4646

4747
The default environments are `Development` for build and `Production` for publish.
4848

49+
There are several approaches for setting the environment in a standalone Blazor WebAssembly app during build/publish operations and one approach for an app starting or running on the client:
50+
51+
* Set the property value when `dotnet build` or `dotnet publish` is executed. The following example sets the environment to `Staging` when an app is published:
52+
53+
```dotnetcli
54+
dotnet publish -p:WasmApplicationEnvironmentName=Staging
55+
```
56+
57+
* Set the property during build or publish based on the app's configuration in Visual Studio. The following property groups can be used in the app's project file or any publish configuration file (`.pubxml`). Add additional property groups for other build configurations in use.
58+
59+
```xml
60+
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
61+
<WasmApplicationEnvironmentName>Development</WasmApplicationEnvironmentName>
62+
</PropertyGroup>
63+
64+
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
65+
<WasmApplicationEnvironmentName>Production</WasmApplicationEnvironmentName>
66+
</PropertyGroup>
67+
```
68+
69+
* The environment can be set based on the use of a publish profile. In the following example, the first condition sets the environment to `Development` when no publish profile is used (applies to both build and publish operations without a profile), while the second condition covers setting the environment to `Production` when any publish profile is used:
70+
71+
```xml
72+
<PropertyGroup Condition="'$(PublishProfile)' == ''">
73+
<WasmApplicationEnvironmentName>Development</WasmApplicationEnvironmentName>
74+
</PropertyGroup>
75+
76+
<PropertyGroup Condition="'$(PublishProfile)' != ''">
77+
<WasmApplicationEnvironmentName>Production</WasmApplicationEnvironmentName>
78+
</PropertyGroup>
79+
```
80+
81+
* Create a custom server-side web API endpoint. The standalone Blazor WebAssembly app requests its environment from the web API either at app startup or on-demand while it's running. The value should be passed to [`WebAssemblyStartOptions`](https://github.com/dotnet/aspnetcore/blob/main/src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts#L7) or with [`withApplicationEnvironment`](https://github.com/dotnet/aspnetcore/blob/main/src/Components/dotnet-runtime-js/dotnet.d.ts#L110).
82+
83+
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
84+
4985
:::moniker-end
5086

5187
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"

aspnetcore/release-notes/aspnetcore-10/includes/blazor.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ The default environments are:
207207
* `Development` for build.
208208
* `Production` for publish.
209209

210+
For more information, see <xref:blazor/fundamentals/environments#set-the-environment>.
211+
210212
### Boot configuration file inlined
211213

212214
Blazor's boot configuration, which prior to the release of .NET 10 existed in a file named `blazor.boot.json`, has been inlined into the `dotnet.js` script. This only affects developers who are interacting directly with the `blazor.boot.json` file, such as when developers are:

0 commit comments

Comments
 (0)