Skip to content

Commit 5102616

Browse files
authored
Blazor Preview 7 coverage (#35919)
1 parent d4bbd01 commit 5102616

File tree

15 files changed

+393
-150
lines changed

15 files changed

+393
-150
lines changed

aspnetcore/blazor/components/integration.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,13 @@ In `Pages/_Host.cshtml` of Blazor apps that are `ServerPrerendered` in a Blazor
408408

409409
<!-- UPDATE 10.0 - API cross-link -->
410410

411-
Decide what state to persist using the <xref:Microsoft.AspNetCore.Components.PersistentComponentState> service. The `[SupplyParameterFromPersistentComponentState]` attribute applied to a property registers a callback to persist the state during prerendering and loads it when the component renders interactively or the service is instantiated.
411+
Decide what state to persist using the <xref:Microsoft.AspNetCore.Components.PersistentComponentState> service. The `[PersistentState]` attribute applied to a property registers a callback to persist the state during prerendering and loads it when the component renders interactively or the service is instantiated.
412412

413413
In the following example, the `{TYPE}` placeholder represents the type of data to persist (for example, `WeatherForecast[]`).
414414

415415
```razor
416416
@code {
417-
[SupplyParameterFromPersistentComponentState]
417+
[PersistentState]
418418
public {TYPE} Data { get; set; }
419419
420420
protected override async Task OnInitializedAsync()
@@ -469,7 +469,7 @@ else
469469
}
470470
471471
@code {
472-
[SupplyParameterFromPersistentComponentState]
472+
[PersistentState]
473473
public WeatherForecast[]? Forecasts { get; set; }
474474
475475
protected override async Task OnInitializedAsync()

aspnetcore/blazor/components/layouts.md

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -304,31 +304,17 @@ Specifying the layout as a default layout in the <xref:Microsoft.AspNetCore.Comp
304304

305305
### Apply a layout to arbitrary content (`LayoutView` component)
306306

307-
To set a layout for arbitrary Razor template content, specify the layout with a <xref:Microsoft.AspNetCore.Components.LayoutView> component. You can use a <xref:Microsoft.AspNetCore.Components.LayoutView> in any Razor component. The following example sets a layout component named `ErrorLayout` for the `MainLayout` component's <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> template (`<NotFound>...</NotFound>`).
307+
To set a layout for arbitrary Razor template content, specify the layout with a <xref:Microsoft.AspNetCore.Components.LayoutView> component. You can use a <xref:Microsoft.AspNetCore.Components.LayoutView> in any Razor component. The following example sets a layout component named `ErrorLayout` for the component that includes the following Razor markup.
308308

309309
```razor
310-
<Router ...>
311-
<Found ...>
312-
...
313-
</Found>
314-
<NotFound>
315-
<LayoutView Layout="typeof(ErrorLayout)">
316-
<h1>Page not found</h1>
317-
<p>Sorry, there's nothing at this address.</p>
318-
</LayoutView>
319-
</NotFound>
320-
</Router>
310+
<LayoutView Layout="typeof(ErrorLayout)">
311+
<h1>Page not found</h1>
312+
<p>Sorry, there's nothing at this address.</p>
313+
</LayoutView>
321314
```
322315

323316
You may need to identity the layout's namespace depending on the .NET version and type of Blazor app. For more information, see the [Make the layout namespace available](#make-the-layout-namespace-available) section.
324317

325-
:::moniker range=">= aspnetcore-8.0"
326-
327-
> [!IMPORTANT]
328-
> Blazor Web Apps don't use the <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> parameter (`<NotFound>...</NotFound>` markup), but the parameter is supported for backward compatibility to avoid a breaking change in the framework. The server-side ASP.NET Core middleware pipeline processes requests on the server. Use server-side techniques to handle bad requests. For more information, see <xref:blazor/components/render-modes#static-server-side-rendering-static-ssr>.
329-
330-
:::moniker-end
331-
332318
:::moniker range="= aspnetcore-5.0"
333319

334320
[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]

aspnetcore/blazor/components/lifecycle.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ else
636636
}
637637
638638
@code {
639-
[SupplyParameterFromPersistentComponentState]
639+
[PersistentState]
640640
public string? Data { get; set; }
641641
642642
protected override async Task OnInitializedAsync()

aspnetcore/blazor/components/render-modes.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,21 @@ In the following example, there's no designation for the component's render mode
339339

340340
If using the preceding component locally in a Blazor Web App, place the component in the server project's `Components/Pages` folder. The server project is the solution's project with a name that doesn't end in `.Client`. When the app is running, navigate to `/render-mode-1` in the browser's address bar.
341341

342+
:::moniker range=">= aspnetcore-10.0"
343+
344+
During static SSR, Razor component page requests are processed by server-side ASP.NET Core middleware pipeline request processing for authorization. Dedicated Blazor features for authorization aren't operational because Razor components aren't rendered during server-side request processing. Blazor router features in the `Routes` component that aren't available during static SSR include displaying [Not Authorized content (`<NotAuthorized>...</NotAuthorized>`)](xref:blazor/security/index#authorizeview-component) (<xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.NotAuthorized>). Blazor Web Apps typically process unauthorized requests on the server by [customizing the behavior of Authorization Middleware](xref:security/authorization/authorizationmiddlewareresulthandler).
345+
346+
:::moniker-end
347+
348+
:::moniker range="< aspnetcore-10.0"
349+
342350
During static SSR, Razor component page requests are processed by server-side ASP.NET Core middleware pipeline request processing for routing and authorization. Dedicated Blazor features for routing and authorization aren't operational because Razor components aren't rendered during server-side request processing. Blazor router features in the `Routes` component that aren't available during static SSR include displaying:
343351

344-
* [Not authorized content (`<NotAuthorized>...</NotAuthorized>`)](xref:blazor/security/index#authorizeview-component) (<xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.NotAuthorized>): Blazor Web Apps typically process unauthorized requests on the server by [customizing the behavior of Authorization Middleware](xref:security/authorization/authorizationmiddlewareresulthandler).
352+
* [Not Authorized content (`<NotAuthorized>...</NotAuthorized>`)](xref:blazor/security/index#authorizeview-component) (<xref:Microsoft.AspNetCore.Components.Authorization.AuthorizeRouteView.NotAuthorized>): Blazor Web Apps typically process unauthorized requests on the server by [customizing the behavior of Authorization Middleware](xref:security/authorization/authorizationmiddlewareresulthandler).
353+
354+
* [Not Found content (`<NotFound>...</NotFound>`)](xref:blazor/fundamentals/routing#provide-custom-content-when-content-isnt-found) (<xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound>): Blazor Web Apps typically process bad URL requests on the server by either displaying the browser's built-in 404 UI or returning a custom 404 page (or other response) via ASP.NET Core middleware (for example, [`UseStatusCodePagesWithRedirects`](xref:fundamentals/error-handling#usestatuscodepageswithredirects) / [API documentation](xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithRedirects%2A)).
345355

346-
* [Not found content (`<NotFound>...</NotFound>`)](xref:blazor/fundamentals/routing#provide-custom-content-when-content-isnt-found) (<xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound>): Blazor Web Apps typically process bad URL requests on the server by either displaying the browser's built-in 404 UI or returning a custom 404 page (or other response) via ASP.NET Core middleware (for example, [`UseStatusCodePagesWithRedirects`](xref:fundamentals/error-handling#usestatuscodepageswithredirects) / [API documentation](xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithRedirects%2A)). For more information, see [Create simpler way to show Not Found 404 UI with Blazor (`dotnet/aspnetcore` #45654)](https://github.com/dotnet/aspnetcore/issues/45654).
356+
:::moniker-end
347357

348358
If the app exhibits root-level interactivity, server-side ASP.NET Core request processing isn't involved after the initial static SSR, which means that the preceding Blazor features work as expected.
349359

aspnetcore/blazor/debug.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,27 @@ VsRegEdit.exe set "<VSInstallFolder>" HKCU JSDebugger\Options\Debugging "BlazorT
516516
```
517517

518518
The `{TIMEOUT}` placeholder in the preceding command is in milliseconds. For example, one minute is assigned as `60000`.
519+
520+
:::moniker range=">= aspnetcore-10.0"
521+
522+
## Control Hot Reload
523+
524+
The `WasmEnableHotReload` MSBuild property enables [Hot Reload](xref:test/hot-reload) and is set to `true` by default when building in the `Debug` configuration. Hot Reload isn't enabled (set to `false`) when building in any other configuration.
525+
526+
To use a custom configuration name when debugging, for example, `DebugWebAssembly`, set the property to `true` to enable Hot Reload:
527+
528+
```xml
529+
<PropertyGroup>
530+
<WasmEnableHotReload>true</WasmEnableHotReload>
531+
</PropertyGroup>
532+
```
533+
534+
To disable Hot Reload for the `Debug` configuration, set the value to `false`:
535+
536+
```xml
537+
<PropertyGroup>
538+
<WasmEnableHotReload>false</WasmEnableHotReload>
539+
</PropertyGroup>
540+
```
541+
542+
:::moniker-end

aspnetcore/blazor/forms/input-components.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,36 @@ Assign a custom template to <xref:Microsoft.AspNetCore.Components.Forms.InputDat
556556
> The ProductionDate field has an incorrect date value.
557557

558558
:::moniker-end
559+
560+
:::moniker range=">= aspnetcore-10.0"
561+
562+
## `InputHidden` component to handle hidden input fields in forms
563+
564+
<!-- UPDATE 10.0 - API doc cross-link -->
565+
566+
The `InputHidden` component provides a hidden input field for storing string values.
567+
568+
In the following example, a hidden input field is created for the form's `Parameter` property. When the form is submitted, the value of the hidden field is displayed:
569+
570+
```razor
571+
<EditForm Model="Parameter" OnValidSubmit="Submit" FormName="InputHidden Example">
572+
<InputHidden id="hidden" @bind-Value="Parameter" />
573+
<button type="submit">Submit</button>
574+
</EditForm>
575+
576+
@if (submitted)
577+
{
578+
<p>Hello @Parameter!</p>
579+
}
580+
581+
@code {
582+
private bool submitted;
583+
584+
[SupplyParameterFromForm]
585+
public string Parameter { get; set; } = "stranger";
586+
587+
private void Submit() => submitted = true;
588+
}
589+
```
590+
591+
:::moniker-end

aspnetcore/blazor/fundamentals/routing.md

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ When the <xref:Microsoft.AspNetCore.Components.Routing.Router> component navigat
136136

137137
:::moniker-end
138138

139+
:::moniker range="< aspnetcore-10.0"
140+
139141
## Provide custom content when content isn't found
140142

141143
The <xref:Microsoft.AspNetCore.Components.Routing.Router> component allows the app to specify custom content if content isn't found for the requested route.
@@ -153,14 +155,14 @@ Set custom content for the <xref:Microsoft.AspNetCore.Components.Routing.Router>
153155

154156
Arbitrary items are supported as content of the <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> parameter, such as other interactive components. To apply a default layout to <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> content, see <xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component>.
155157

156-
:::moniker range=">= aspnetcore-8.0"
158+
Blazor Web Apps don't use the <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> parameter (`<NotFound>...</NotFound>` markup), but the parameter is supported&dagger; for backward compatibility in .NET 8/9 to avoid a breaking change in the framework. The server-side ASP.NET Core middleware pipeline processes requests on the server. Use server-side techniques to handle bad requests.
157159

158-
> [!IMPORTANT]
159-
> Blazor Web Apps don't use the <xref:Microsoft.AspNetCore.Components.Routing.Router.NotFound> parameter (`<NotFound>...</NotFound>` markup), but the parameter is supported&dagger; for backward compatibility to avoid a breaking change in the framework. The server-side ASP.NET Core middleware pipeline processes requests on the server. Use server-side techniques to handle bad requests.
160-
>
161-
> &dagger;*Supported* in this context means that placing `<NotFound>...</NotFound>` markup doesn't result in an exception, but using the markup isn't effective either.
162-
>
163-
> For more information, including a recommended approach for handling bad requests, see <xref:blazor/components/render-modes#static-server-side-rendering-static-ssr>.
160+
&dagger;*Supported* in this context means that placing `<NotFound>...</NotFound>` markup doesn't result in an exception, but using the markup isn't effective either.
161+
162+
For more information, see the following resources:
163+
164+
* <xref:blazor/components/render-modes#static-server-side-rendering-static-ssr>
165+
* [Not Found responses](#not-found-responses) section
164166

165167
:::moniker-end
166168

@@ -714,24 +716,22 @@ For more information on component disposal, see <xref:blazor/components/componen
714716

715717
* **Interactive rendering**: Signals the Blazor router ([`Router` component](xref:blazor/fundamentals/routing#route-templates)) to render Not Found content.
716718

717-
* **Streaming rendering**: If [enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling) is active, [streaming rendering](xref:blazor/components/rendering#streaming-rendering) renders Not Found content without reloading the page. When enhanced navigation is blocked, the framework redirects to Not Found content with a page refresh.
719+
* **Streaming rendering**: If [enhanced navigation](xref:blazor/fundamentals/routing?view=aspnetcore-10.0#enhanced-navigation-and-form-handling) is active, [streaming rendering](xref:blazor/components/rendering#streaming-rendering) renders Not Found content without reloading the page. When enhanced navigation is blocked, the framework redirects to Not Found content with a page refresh.
718720

719721
> [!NOTE]
720722
> The following discussion mentions that a Not Found Razor component can be assigned to the `Router` component's `NotFoundPage` parameter. The parameter works in concert with `NavigationManager.NotFound` and is described in more detail later in this section.
721723
722-
Streaming rendering can only render components that have a route, such as a Not Found page assignment with the `Router` component's `NotFoundPage` parameter 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.
723-
724-
Streaming `NavigationManager.NotFound` content rendering uses (in order):
724+
Streaming rendering can only render components that have a route, such as a `NotFoundPage` assignment (`NotFoundPage="..."`) or a [Status Code Pages Re-execution Middleware page assignment](xref:fundamentals/error-handling#usestatuscodepageswithreexecute) (<xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithReExecute%2A>). `DefaultNotFound` 404 content ("`Not found`" plain text) doesn't have a route, so it can't be used during streaming rendering.
725725

726-
* A `NotFoundPage` passed to the `Router` component, if present.
727-
* A Status Code Pages Re-execution Middleware page, if configured.
728-
* No action if neither of the preceding approaches is adopted.
726+
> [!NOTE]
727+
> The Not Found render fragment (`<NotFound>...</NotFound>`) isn't supported in .NET 10 or later.
729728
730-
Non-streaming `NavigationManager.NotFound` content rendering uses (in order):
729+
`NavigationManager.NotFound` content rendering uses the following, regardless if the response has started or not (in order):
731730

732-
* A `NotFoundPage` passed to the `Router` component, if present.
733-
* Not Found render fragment content, if present. *Not recommended in .NET 10 or later.*
734-
* `DefaultNotFound` 404 content ("`Not found`" plain text).
731+
* If <xref:Microsoft.AspNetCore.Components.Routing.NotFoundEventArgs.Path%2A?displayProperty=nameWithType> is set, render the contents of the assigned page.
732+
* If `Router.NotFoundPage` is set, render the assigned page.
733+
* A Status Code Pages Re-execution Middleware page, if configured.
734+
* No action if none of the preceding approaches are adopted.
735735

736736
[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.
737737

@@ -796,9 +796,52 @@ When a component is rendered with a global interactive render mode, calling `Not
796796

797797
You can use the `OnNotFound` event for notifications when `NotFound` is invoked. The event is only fired when `NotFound` is called, not for any 404 response. For example, setting `HttpContextAccessor.HttpContext.Response.StatusCode` to `404` doesn't trigger `NotFound`/`OnNotFound`.
798798

799-
<!-- UPDATE 10.0 - For Pre5, the following can be expanded to
800-
cover CSR with an added bit of coverage for
801-
Re-execution Middleware. -->
799+
Apps that implement a custom router can also use `NavigationManager.NotFound`. The custom router can render Not Found content from two sources, depending on the state of the response:
800+
801+
* Regardless of the response state, the re-execution path to the page can used by passing it to <xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithReExecute%2A>:
802+
803+
```csharp
804+
app.UseStatusCodePagesWithReExecute(
805+
"/not-found", createScopeForStatusCodePages: true);
806+
```
807+
808+
* When the response has started, the <xref:Microsoft.AspNetCore.Components.Routing.NotFoundEventArgs.Path%2A?displayProperty=nameWithType> can be used by subscribing to the `OnNotFoundEvent` in the router:
809+
810+
```razor
811+
@code {
812+
[CascadingParameter]
813+
public HttpContext? HttpContext { get; set; }
814+
815+
private void OnNotFoundEvent(object sender, NotFoundEventArgs e)
816+
{
817+
// Only execute the logic if HTTP response has started,
818+
// because setting NotFoundEventArgs.Path blocks re-execution
819+
if (HttpContext?.Response.HasStarted == false)
820+
{
821+
return;
822+
}
823+
824+
var type = typeof(CustomNotFoundPage);
825+
var routeAttributes = type.GetCustomAttributes<RouteAttribute>(inherit: true);
826+
827+
if (routeAttributes.Length == 0)
828+
{
829+
throw new InvalidOperationException($"The type {type.FullName} " +
830+
$"doesn't have a {nameof(RouteAttribute)} applied.");
831+
}
832+
833+
var routeAttribute = (RouteAttribute)routeAttributes[0];
834+
835+
if (routeAttribute.Template != null)
836+
{
837+
e.Path = routeAttribute.Template;
838+
}
839+
}
840+
}
841+
```
842+
843+
<!-- UPDATE 10.0 - Thus far, it looks like we're removing
844+
the following scenario.
802845
803846
In the following example for components that adopt [interactive server-side rendering (interactive SSR)](xref:blazor/fundamentals/index#client-and-server-rendering-concepts), custom content is rendered depending on where `OnNotFound` is called. If the event is triggered by the following `Movie` component when a movie isn't found on component initialization, a custom message states that the requested movie isn't found. If the event is triggered by the `User` component, a different message states that the user isn't found.
804847
@@ -851,6 +894,8 @@ The `Routes` component (`Routes.razor`):
851894
</Router>
852895
```
853896
897+
-->
898+
854899
In the following example components:
855900

856901
* The `NotFoundContext` service is injected, along with the <xref:Microsoft.AspNetCore.Components.NavigationManager>.

0 commit comments

Comments
 (0)