Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions aspnetcore/blazor/components/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,13 @@ In `Pages/_Host.cshtml` of Blazor apps that are `ServerPrerendered` in a Blazor

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

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

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

```razor
@code {
[SupplyParameterFromPersistentComponentState]
[PersistentState]
public {TYPE} Data { get; set; }

protected override async Task OnInitializedAsync()
Expand Down Expand Up @@ -469,7 +469,7 @@ else
}

@code {
[SupplyParameterFromPersistentComponentState]
[PersistentState]
public WeatherForecast[]? Forecasts { get; set; }

protected override async Task OnInitializedAsync()
Expand Down
24 changes: 5 additions & 19 deletions aspnetcore/blazor/components/layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,31 +304,17 @@ Specifying the layout as a default layout in the <xref:Microsoft.AspNetCore.Comp

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

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>`).
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.

```razor
<Router ...>
<Found ...>
...
</Found>
<NotFound>
<LayoutView Layout="typeof(ErrorLayout)">
<h1>Page not found</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<LayoutView Layout="typeof(ErrorLayout)">
<h1>Page not found</h1>
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
```

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.

:::moniker range=">= aspnetcore-8.0"

> [!IMPORTANT]
> 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>.

:::moniker-end

:::moniker range="= aspnetcore-5.0"

[!INCLUDE[](~/blazor/includes/prefer-exact-matches.md)]
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ else
}

@code {
[SupplyParameterFromPersistentComponentState]
[PersistentState]
public string? Data { get; set; }

protected override async Task OnInitializedAsync()
Expand Down
14 changes: 12 additions & 2 deletions aspnetcore/blazor/components/render-modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,21 @@ In the following example, there's no designation for the component's render mode

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.

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

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).

:::moniker-end

:::moniker range="< aspnetcore-10.0"

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:

* [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).
* [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).

* [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)).

* [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).
:::moniker-end

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.

Expand Down
33 changes: 33 additions & 0 deletions aspnetcore/blazor/forms/input-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,36 @@ Assign a custom template to <xref:Microsoft.AspNetCore.Components.Forms.InputDat
> The ProductionDate field has an incorrect date value.

:::moniker-end

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

## `InputHidden` component to handle hidden input fields in forms

<!-- UPDATE 10.0 - API doc cross-link -->

The `InputHidden` component provides a hidden input field for storing string values.

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:

```razor
<EditForm Model="Parameter" OnValidSubmit="Submit" FormName="InputHidden Example">
<InputHidden id="hidden" @bind-Value="Parameter" />
<button type="submit">Submit</button>
</EditForm>

@if (submitted)
{
<p>Hello @Parameter!</p>
}

@code {
private bool submitted;

[SupplyParameterFromForm]
public string Parameter { get; set; } = "stranger";

private void Submit() => submitted = true;
}
```

:::moniker-end
88 changes: 67 additions & 21 deletions aspnetcore/blazor/fundamentals/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ When the <xref:Microsoft.AspNetCore.Components.Routing.Router> component navigat

:::moniker-end

:::moniker range="< aspnetcore-10.0"

## Provide custom content when content isn't found

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

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

:::moniker range=">= aspnetcore-8.0"
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.

> [!IMPORTANT]
> 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.
>
> &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.
>
> For more information, including a recommended approach for handling bad requests, see <xref:blazor/components/render-modes#static-server-side-rendering-static-ssr>.
&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.

For more information, see the following resources:

* <xref:blazor/components/render-modes#static-server-side-rendering-static-ssr>
* [Not Found responses](#not-found-responses) section

:::moniker-end

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

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

* **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.
* **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.

> [!NOTE]
> 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.

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.

Streaming `NavigationManager.NotFound` content rendering uses (in order):
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.

* A `NotFoundPage` passed to the `Router` component, if present.
* A Status Code Pages Re-execution Middleware page, if configured.
* No action if neither of the preceding approaches is adopted.
> [!NOTE]
> The Not Found render fragment (`<NotFound>...</NotFound>`) isn't supported in .NET 10 or later.

Non-streaming `NavigationManager.NotFound` content rendering uses (in order):
`NavigationManager.NotFound` content rendering uses the following, regardless if the response has started or not (in order):

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

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

Expand Down Expand Up @@ -796,9 +796,53 @@ When a component is rendered with a global interactive render mode, calling `Not

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`.

<!-- UPDATE 10.0 - For Pre5, the following can be expanded to
cover CSR with an added bit of coverage for
Re-execution Middleware. -->
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:

* 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>:

```csharp
app.UseStatusCodePagesWithReExecute(
"/not-found", createScopeForStatusCodePages: true);
```

* 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:

```razor
@code {
[CascadingParameter]
public HttpContext? HttpContext { get; set; }

private void OnNotFoundEvent(object sender, NotFoundEventArgs e)
{
// Only execute the logic if HTTP response has started,
// because setting NotFoundEventArgs.Path blocks re-execution
if (HttpContext?.Response.HasStarted == false)
{
return;
}

var type = typeof(CustomNotFoundPage);
var routeAttributes = type.GetCustomAttributes(typeof(RouteAttribute),
inherit: true);

if (routeAttributes.Length == 0)
{
throw new InvalidOperationException($"The type {type.FullName} " +
$"doesn't have a {typeof(RouteAttribute).FullName} applied.");
}

var routeAttribute = (RouteAttribute)routeAttributes[0];

if (routeAttribute.Template != null)
{
e.Path = routeAttribute.Template;
}
}
}
```

<!-- UPDATE 10.0 - Thus far, it looks like we're removing
the following scenario.

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.

Expand Down Expand Up @@ -851,6 +895,8 @@ The `Routes` component (`Routes.razor`):
</Router>
```

-->

In the following example components:

* The `NotFoundContext` service is injected, along with the <xref:Microsoft.AspNetCore.Components.NavigationManager>.
Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/blazor/host-and-deploy/server/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ Each circuit uses approximately 250 KB of memory for a minimal *Hello World*-sty

## Blazor WebAssembly static asset preloading

The `LinkPreload` component in the `App` component's head content (`App.razor`) is used to reference Blazor static assets. The component is placed after the base URL tag (`<base>`):
The `ResourcePreloader` component in the `App` component's head content (`App.razor`) is used to reference Blazor static assets. The component is placed after the base URL tag (`<base>`):

```razor
<LinkPreload />
<ResourcePreloader />
```

A Razor component is used instead of `<link>` elements because:

* The component permits the base URL (`<base>` tag's `href` attribute value) to correctly identify the root of the Blazor app within an ASP.NET Core app.
* The feature can be removed by removing the `LinkPreload` component tag from the `App` component. This is helpful in cases where the app is using a [`loadBootResource` callback](xref:blazor/fundamentals/startup#load-client-side-boot-resources) to modify URLs.
* The feature can be removed by removing the `ResourcePreloader` component tag from the `App` component. This is helpful in cases where the app is using a [`loadBootResource` callback](xref:blazor/fundamentals/startup#load-client-side-boot-resources) to modify URLs.

:::moniker-end

Expand Down
Loading