Skip to content

Commit 06b41c0

Browse files
authored
Merge branch 'main' into blazor_otel_names
2 parents dde0619 + ab959ee commit 06b41c0

File tree

219 files changed

+3338
-1310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

219 files changed

+3338
-1310
lines changed

.openpublishing.redirection.json

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,16 @@
10101010
"redirect_url": "/aspnet/core/migration/fx-to-core/systemweb-adapters",
10111011
"redirect_document_id": false
10121012
},
1013+
{
1014+
"source_path": "aspnetcore/migration/inc/unit-testing.md",
1015+
"redirect_url": "/aspnet/core/migration/fx-to-core/systemweb-adapters",
1016+
"redirect_document_id": false
1017+
},
1018+
{
1019+
"source_path": "aspnetcore/migration/fx-to-core/inc/unit-testing.md",
1020+
"redirect_url": "/aspnet/core/migration/fx-to-core/systemweb-adapters",
1021+
"redirect_document_id": false
1022+
},
10131023
{
10141024
"source_path": "aspnetcore/migration/inc/blazor.md",
10151025
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/blazor",
@@ -1022,7 +1032,7 @@
10221032
},
10231033
{
10241034
"source_path": "aspnetcore/migration/inc/overview.md",
1025-
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/overview",
1035+
"redirect_url": "/aspnet/core/migration/fx-to-core/index",
10261036
"redirect_document_id": false
10271037
},
10281038
{
@@ -1047,24 +1057,44 @@
10471057
},
10481058
{
10491059
"source_path": "aspnetcore/migration/inc/start.md",
1050-
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/start",
1060+
"redirect_url": "/aspnet/core/migration/fx-to-core/start",
10511061
"redirect_document_id": false
10521062
},
10531063
{
1054-
"source_path": "aspnetcore/migration/inc/unit-testing.md",
1055-
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/unit-testing",
1064+
"source_path": "aspnetcore/migration/inc/usage_guidance.md",
1065+
"redirect_url": "/aspnet/core/migration/fx-to-core/",
10561066
"redirect_document_id": false
10571067
},
10581068
{
1059-
"source_path": "aspnetcore/migration/inc/usage_guidance.md",
1060-
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/usage_guidance",
1069+
"source_path": "aspnetcore/migration/fx-to-core/inc/usage_guidance.md",
1070+
"redirect_url": "/aspnet/core/migration/fx-to-core/",
10611071
"redirect_document_id": false
10621072
},
10631073
{
10641074
"source_path": "aspnetcore/migration/inc/wrapped.md",
10651075
"redirect_url": "/aspnet/core/migration/fx-to-core/inc/wrapped",
10661076
"redirect_document_id": false
10671077
},
1078+
{
1079+
"source_path": "aspnetcore/migration/fx-to-core/inc/remote-session.md",
1080+
"redirect_url": "/aspnet/core/migration/fx-to-core/areas/session#remote-app-session-state",
1081+
"redirect_document_id": false
1082+
},
1083+
{
1084+
"source_path": "aspnetcore/migration/fx-to-core/inc/remote-authentication.md",
1085+
"redirect_url": "/aspnet/core/migration/fx-to-core/areas/authentication#remote-authentication",
1086+
"redirect_document_id": false
1087+
},
1088+
{
1089+
"source_path": "aspnetcore/migration/fx-to-core/inc/session.md",
1090+
"redirect_url": "/aspnet/core/migration/fx-to-core/areas/session",
1091+
"redirect_document_id": false
1092+
},
1093+
{
1094+
"source_path": "aspnetcore/migration/fx-to-core/inc/wrapped.md",
1095+
"redirect_url": "/aspnet/core/migration/fx-to-core/areas/session#wrapped-aspnet-core-session-state",
1096+
"redirect_document_id": false
1097+
},
10681098
{
10691099
"source_path": "aspnetcore/security/blazor/server-side.md",
10701100
"redirect_url": "/aspnet/core/blazor/security/server/",
@@ -1522,6 +1552,11 @@
15221552
"source_path": "aspnetcore/migration/identity.md",
15231553
"redirect_url": "/aspnet/core/migration/fx-to-core/examples/identity",
15241554
"redirect_document_id": false
1555+
},
1556+
{
1557+
"source_path": "aspnetcore/blazor/progressive-web-app.md",
1558+
"redirect_url": "/aspnet/core/blazor/progressive-web-app/",
1559+
"redirect_document_id": false
15251560
}
15261561
]
15271562
}

aspnetcore/blazor/components/prerender.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ In the following example that serializes state for multiple components of the sa
202202
In the following example that serializes state for a dependency injection service:
203203

204204
* Properties annotated with the `[SupplyParameterFromPersistentComponentState]` attribute are serialized during prerendering and deserialized when the app becomes interactive.
205-
* The `AddPersistentService` method is used to register the service for persistence. The render mode is required because the render mode can't be inferred from the service type. Use any of the following values:
205+
* The <xref:Microsoft.Extensions.DependencyInjection.RazorComponentsRazorComponentBuilderExtensions.RegisterPersistentService%2A> extension method is used to register the service for persistence. The render mode is required because the render mode can't be inferred from the service type. Use any of the following values:
206206
* `RenderMode.Server`: The service is available for the Interactive Server render mode.
207207
* `RenderMode.Webassembly`: The service is available for the Interactive Webassembly render mode.
208208
* `RenderMode.InteractiveAuto`: The service is available for both the Interactive Server and Interactive Webassembly render modes if a component renders in either of those modes.
@@ -231,7 +231,8 @@ public class CounterService
231231
In `Program.cs`:
232232

233233
```csharp
234-
builder.Services.AddPersistentService<CounterService>(RenderMode.InteractiveAuto);
234+
builder.Services.RegisterPersistentService<CounterService>(
235+
RenderMode.InteractiveAuto);
235236
```
236237

237238
Serialized properties are identified from the actual service instance:

aspnetcore/blazor/components/quickgrid.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -602,10 +602,9 @@ dotnet aspnet-codegenerator blazor -h
602602

603603
For an example use of the QuickGrid scaffolder, see <xref:blazor/tutorials/movie-database-app/index>.
604604

605-
<!-- UPDATE 10.0 - PU work tracked by https://github.com/dotnet/aspnetcore/issues/58716.
606-
Versioning out at 10.0 for now. -->
607-
608-
:::moniker range="< aspnetcore-10.0"
605+
<!-- UPDATE 11.0 - PU work tracked by https://github.com/dotnet/aspnetcore/issues/58716.
606+
We will continue to show this for now. The PU plans to look at it
607+
for framework updates at 11.0. -->
609608

610609
## Multiple concurrent EF Core queries trigger `System.InvalidOperationException`
611610

@@ -690,5 +689,3 @@ Consider the following example, which is based on the movie database `Index` com
690689
}
691690
}
692691
```
693-
694-
:::moniker-end

aspnetcore/blazor/components/render-modes.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,10 @@ Prerendering is enabled by default for interactive components.
221221

222222
Internal navigation for interactive routing doesn't involve requesting new page content from the server. Therefore, prerendering doesn't occur for internal page requests, including for [enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling). For more information, see [Static versus interactive routing](xref:blazor/fundamentals/routing#static-versus-interactive-routing), [Interactive routing and prerendering](xref:blazor/components/prerender#interactive-routing-and-prerendering), and [Enhanced navigation and form handling](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling).
223223

224-
<!-- UPDATE 10.0 Tracking https://github.com/dotnet/aspnetcore/issues/55635
225-
for .NET 10 work in this area. Update the following remark
226-
if changes are made to the framework. -->
224+
<!-- UPDATE 11.0 Tracking https://github.com/dotnet/aspnetcore/issues/55635
225+
for .NET 11 work in this area. -->
227226

228-
Disabling prerendering using the following techniques only takes effect for top-level render modes. If a parent component specifies a render mode, the prerendering settings of its children are ignored. This behavior is under investigation for possible changes with the release of .NET 10 in November, 2025.
227+
Disabling prerendering using the following techniques only takes effect for top-level render modes. If a parent component specifies a render mode, the prerendering settings of its children are ignored.
229228

230229
To disable prerendering for a *component instance*, pass the `prerender` flag with a value of `false` to the render mode:
231230

aspnetcore/blazor/components/rendering.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ Streaming rendering requires the server to avoid buffering the output. The respo
5353

5454
To stream content updates when using static server-side rendering (static SSR) or prerendering, apply the [`[StreamRendering]` attribute](xref:Microsoft.AspNetCore.Components.StreamRenderingAttribute) in .NET 9 or later (use `[StreamRendering(true)]` in .NET 8) to the component. Streaming rendering must be explicitly enabled because streamed updates may cause content on the page to shift. Components without the attribute automatically adopt streaming rendering if the parent component uses the feature. Pass `false` to the attribute in a child component to disable the feature at that point and further down the component subtree. The attribute is functional when applied to components supplied by a [Razor class library](xref:blazor/components/class-libraries).
5555

56+
:::moniker-end
57+
58+
:::moniker range=">= aspnetcore-10.0"
59+
60+
If [enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling) is active, streaming rendering renders [Not Found responses](xref:blazor/fundamentals/routing#not-found-responses) without reloading the page. When enhanced navigation is blocked, the framework redirects to Not Found content with a page refresh.
61+
62+
Streaming rendering can only render components that have a route, such as a [`NotFoundPage` assignment](xref:blazor/fundamentals/routing#not-found-responses) (`NotFoundPage="..."`) or a [Status Code Pages Re-execution Middleware page assignment](xref:fundamentals/error-handling#usestatuscodepageswithreexecute) (<xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithReExecute%2A>). The Not Found render fragment (`<NotFound>...</NotFound>`) and the `DefaultNotFound` 404 content ("`Not found`" plain text) don't have routes, so they can't be used during streaming rendering.
63+
64+
Streaming `NavigationManager.NotFound` content rendering uses (in order):
65+
66+
* A `NotFoundPage` passed to the `Router` component, if present.
67+
* A Status Code Pages Re-execution Middleware page, if configured.
68+
* No action if neither of the preceding approaches is adopted.
69+
70+
Non-streaming `NavigationManager.NotFound` content rendering uses (in order):
71+
72+
* A `NotFoundPage` passed to the `Router` component, if present.
73+
* Not Found render fragment content, if present. *Not recommended in .NET 10 or later.*
74+
* `DefaultNotFound` 404 content ("`Not found`" plain text).
75+
76+
[Status Code Pages Re-execution Middleware](xref:fundamentals/error-handling#usestatuscodepageswithreexecute) with <xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithReExecute%2A> takes precedence for browser-based address routing problems, such as an incorrect URL typed into the browser's address bar or selecting a link that has no endpoint in the app.
77+
78+
:::moniker-end
79+
80+
:::moniker range=">= aspnetcore-8.0"
81+
5682
The following example is based on the `Weather` component in an app created from the [Blazor Web App project template](xref:blazor/project-structure#blazor-web-app). The call to <xref:System.Threading.Tasks.Task.Delay%2A?displayProperty=nameWithType> simulates retrieving weather data asynchronously. The component initially renders placeholder content ("`Loading...`") without waiting for the asynchronous delay to complete. When the asynchronous delay completes and the weather data content is generated, the content is streamed to the response and patched into the weather forecast table.
5783

5884
`Weather.razor`:

aspnetcore/blazor/forms/validation.md

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1557,12 +1557,108 @@ The <xref:System.ComponentModel.DataAnnotations.CompareAttribute> doesn't work w
15571557

15581558
:::moniker-end
15591559

1560-
## Nested models, collection types, and complex types
1560+
:::moniker range=">= aspnetcore-10.0"
1561+
1562+
## Nested objects and collection types
1563+
1564+
Blazor form validation includes support for validating properties of nested objects and collection items with the built-in <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator>.
1565+
1566+
To create a validated form, use a <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component inside an <xref:Microsoft.AspNetCore.Components.Forms.EditForm> component, just as before.
1567+
1568+
To opt into the nested objects and collection types validation feature:
1569+
1570+
<!-- UPDATE 10.0 - API cross-links -->
1571+
1572+
1. Call the `AddValidation` extension method in the `Program` file where services are registered.
1573+
2. Declare the form model types in a C# class file, not in a Razor component (`.razor`).
1574+
3. Annotate the root form model type with the `[ValidatableType]` attribute.
1575+
1576+
Without following the preceding steps, form validation behavior doesn't include nested model and collection type validation.
1577+
1578+
<!-- UPDATE 10.0 - Replace with a fully working, cut-'n-paste example -->
1579+
1580+
The following example demonstrates customer orders with the improved form validation (details omitted for brevity):
1581+
1582+
In `Program.cs`, call `AddValidation` on the service collection:
1583+
1584+
```csharp
1585+
builder.Services.AddValidation();
1586+
```
1587+
1588+
In the following `Order` class, the `[ValidatableType]` attribute is required on the top-level model type. The other types are discovered automatically. `OrderItem` and `ShippingAddress` aren't shown for brevity, but nested and collection validation works the same way in those types if they were shown.
1589+
1590+
`Order.cs`:
1591+
1592+
```csharp
1593+
[ValidatableType]
1594+
public class Order
1595+
{
1596+
public Customer Customer { get; set; } = new();
1597+
public List<OrderItem> OrderItems { get; set; } = [];
1598+
}
1599+
1600+
public class Customer
1601+
{
1602+
[Required(ErrorMessage = "Name is required.")]
1603+
public string? FullName { get; set; }
1604+
1605+
[Required(ErrorMessage = "Email is required.")]
1606+
public string? Email { get; set; }
1607+
1608+
public ShippingAddress ShippingAddress { get; set; } = new();
1609+
}
1610+
```
1611+
1612+
In the following `OrderPage` component, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> component is present in the <xref:Microsoft.AspNetCore.Components.Forms.EditForm> component.
1613+
1614+
`OrderPage.razor`:
1615+
1616+
```razor
1617+
<EditForm Model="Model">
1618+
<DataAnnotationsValidator />
1619+
1620+
<h3>Customer Details</h3>
1621+
<div class="mb-3">
1622+
<label>
1623+
Full Name
1624+
<InputText @bind-Value="Model!.Customer.FullName" />
1625+
</label>
1626+
<ValidationMessage For="@(() => Model!.Customer.FullName)" />
1627+
</div>
1628+
1629+
// ... form continues ...
1630+
</EditForm>
1631+
1632+
@code {
1633+
public Order? Model { get; set; }
1634+
1635+
protected override void OnInitialized() => Model ??= new();
1636+
}
1637+
```
1638+
1639+
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.
1640+
1641+
## Complex types
1642+
1643+
Blazor provides support for validating form input using data annotations with the built-in <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator>. However, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> only validates top-level properties of the model bound to the form that aren't complex-type properties.
1644+
1645+
To validate the bound model's entire object graph, including complex-type properties, use the `ObjectGraphDataAnnotationsValidator` provided by the *experimental* [`Microsoft.AspNetCore.Components.DataAnnotations.Validation`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.DataAnnotations.Validation) package.
1646+
1647+
> [!NOTE]
1648+
> The `ObjectGraphDataAnnotationsValidator` isn't compatible with [nested objects and collection types validation](#nested-objects-and-collection-types), but it's capable of validating nested objects and collection types on its own.
1649+
1650+
:::moniker-end
1651+
1652+
:::moniker range="< aspnetcore-10.0"
1653+
1654+
## Nested objects, collection types, and complex types
15611655

15621656
Blazor provides support for validating form input using data annotations with the built-in <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator>. However, the <xref:Microsoft.AspNetCore.Components.Forms.DataAnnotationsValidator> only validates top-level properties of the model bound to the form that aren't collection- or complex-type properties.
15631657

15641658
To validate the bound model's entire object graph, including collection- and complex-type properties, use the `ObjectGraphDataAnnotationsValidator` provided by the *experimental* [`Microsoft.AspNetCore.Components.DataAnnotations.Validation`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.DataAnnotations.Validation) package:
15651659

1660+
:::moniker-end
1661+
15661662
```razor
15671663
<EditForm ...>
15681664
<ObjectGraphDataAnnotationsValidator />

aspnetcore/blazor/fundamentals/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,12 @@ var hostname = builder.Configuration["HostName"];
300300

301301
## Cached configuration
302302

303-
Configuration files are cached for offline use. With [Progressive Web Applications (PWAs)](xref:blazor/progressive-web-app), you can only update configuration files when creating a new deployment. Editing configuration files between deployments has no effect because:
303+
Configuration files are cached for offline use. With [Progressive Web Applications (PWAs)](xref:blazor/progressive-web-app/index), you can only update configuration files when creating a new deployment. Editing configuration files between deployments has no effect because:
304304

305305
* Users have cached versions of the files that they continue to use.
306306
* The PWA's `service-worker.js` and `service-worker-assets.js` files must be rebuilt on compilation, which signal to the app on the user's next online visit that the app has been redeployed.
307307

308-
For more information on how background updates are handled by PWAs, see <xref:blazor/progressive-web-app#background-updates>.
308+
For more information on how background updates are handled by PWAs, see <xref:blazor/progressive-web-app/index#background-updates>.
309309

310310
## Options configuration
311311

0 commit comments

Comments
 (0)