From 562c5790f0138d089e84bbab8e5f7182158f03d5 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:32:12 -0400 Subject: [PATCH 1/3] Server-side behaviors during static SSR --- aspnetcore/blazor/components/layouts.md | 16 ++++++++-------- aspnetcore/blazor/components/render-modes.md | 16 ++++++++++++---- aspnetcore/blazor/fundamentals/routing.md | 13 +++++++------ aspnetcore/blazor/security/index.md | 13 +++++++++++++ 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/aspnetcore/blazor/components/layouts.md b/aspnetcore/blazor/components/layouts.md index 927032cbe022..0f86cac7b419 100644 --- a/aspnetcore/blazor/components/layouts.md +++ b/aspnetcore/blazor/components/layouts.md @@ -219,13 +219,6 @@ Specifying the layout as a default layout in the component. You can use a in any Razor component. The following example sets a layout component named `ErrorLayout` for the `MainLayout` component's template (`...`). -:::moniker range=">= aspnetcore-8.0" - -> [!NOTE] -> The following example is specifically for a Blazor WebAssembly app because Blazor Web Apps don't use the template (`...`). However, the template is supported for backward compatibility to avoid a breaking change in the framework. Blazor Web Apps typically process bad URL requests by either displaying the browser's built-in 404 UI or returning a custom 404 page from the ASP.NET Core server via ASP.NET Core middleware (for example, [`UseStatusCodePagesWithRedirects`](xref:fundamentals/error-handling#usestatuscodepageswithredirects) / [API documentation](xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithRedirects%2A)). - -:::moniker-end - ```razor @@ -240,7 +233,14 @@ To set a layout for arbitrary Razor template content, specify the layout with a ``` -You may need to idenfity 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. +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 parameter (`...` 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 . + +:::moniker-end :::moniker range="= aspnetcore-5.0" diff --git a/aspnetcore/blazor/components/render-modes.md b/aspnetcore/blazor/components/render-modes.md index cc9159f68fd0..d14b8fc588d9 100644 --- a/aspnetcore/blazor/components/render-modes.md +++ b/aspnetcore/blazor/components/render-modes.md @@ -257,9 +257,9 @@ Making a root component, such as the `App` component, interactive with the `@ren ## Static server-side rendering (static SSR) -By default, components use the static server-side rendering (static SSR). The component renders to the response stream and interactivity isn't enabled. +By default, components use static server-side rendering (static SSR). The component renders to the response stream and interactivity isn't enabled. -In the following example, there's no designation for the component's render mode, and the component inherits the default render mode from its parent. Therefore, the component is *statically rendered* on the server. The button isn't interactive and doesn't call the `UpdateMessage` method when selected. The value of `message` doesn't change, and the component isn't rerendered in response to UI events. +In the following example, there's no designation for the component's render mode, so the component inherits its render mode from its parent. The parent is the `Routes` component, which doesn't set a render mode for this example, so static SSR is passed down from the root component, which is the `App` component. Therefore, the following component is *statically rendered* on the server. The button isn't interactive and doesn't call the `UpdateMessage` method when selected. The value of `message` doesn't change, and the component isn't rerendered in response to UI events. `RenderMode1.razor`: @@ -280,6 +280,14 @@ 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. +During static SSR, Razor component page requests behave like Razor Pages and participate in 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 (`...`)](xref:blazor/security/index#authorizeview-component) (): Blazor Web Apps typically process unauthorized requests on the server by [customizing the behavior of Authorization Middleware](xref:security/authorization/authorizationmiddlewareresulthandler). + +* [Not found content (`...`)](xref:blazor/fundamentals/routing#provide-custom-content-when-content-isnt-found) (): 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)). + +If the app becomes interactive for either interactive SSR or CSR components after static SSR, the server-side ASP.NET Core request processing is no longer acting on requests, which means that the preceding Blazor features work as expected. + [Enhanced navigation](xref:blazor/fundamentals/routing#enhanced-navigation-and-form-handling) with static SSR requires special attention when loading JavaScript. For more information, see . ## Interactive server-side rendering (interactive SSR) @@ -666,13 +674,13 @@ Each component that must adopt static SSR sets the custom layout and does ***not > > A `null` render mode is effectively the same as not specifying a render mode, which results in the component inheriting its parent's render mode. In this case, the `App` component is rendered using static SSR, so a `null` render mode results in the `Routes` component inheriting static SSR from the `App` component. If a null render mode is specified for a child component whose parent uses an interactive render mode, the child inherits the same interactive render mode. -Nothing further must be done for the components to enforce static SSR than applying the custom layout: +Nothing further must be done for the components to enforce static SSR than applying the custom layout ***without setting an interactive render mode***: ```razor @layout BlazorSample.Components.Layout.StaticSsrLayout ``` -Other components around the app set an appropriate interactive render mode, which upon reflection in the `App` component is applied to the `Routes` component. Interactive components ***avoid*** applying the custom static SSR layout: +Interactive components around the app ***avoid*** applying the custom static SSR layout and ***only set an appropriate interactive render mode***, which upon reflection in the `App` component is applied to the `Routes` component: ```razor @rendermode {INTERACTIVE RENDER MODE} diff --git a/aspnetcore/blazor/fundamentals/routing.md b/aspnetcore/blazor/fundamentals/routing.md index 9c39fa04274b..66f8916a2f84 100644 --- a/aspnetcore/blazor/fundamentals/routing.md +++ b/aspnetcore/blazor/fundamentals/routing.md @@ -132,12 +132,6 @@ When the component navigat ## Provide custom content when content isn't found -:::moniker range=">= aspnetcore-8.0" - -*This section only applies to Blazor WebAssembly apps.* Blazor Web Apps don't use the parameter (`...` markup), but the parameter is supported for backward compatibility to avoid a breaking change in the framework. Blazor Web Apps typically process bad URL requests by either displaying the browser's built-in 404 UI or returning a custom 404 page from the ASP.NET Core server via ASP.NET Core middleware (for example, [`UseStatusCodePagesWithRedirects`](xref:fundamentals/error-handling#usestatuscodepageswithredirects) / [API documentation](xref:Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.UseStatusCodePagesWithRedirects%2A)). - -:::moniker-end - The component allows the app to specify custom content if content isn't found for the requested route. Set custom content for the component's parameter: @@ -153,6 +147,13 @@ Set custom content for the Arbitrary items are supported as content of the parameter, such as other interactive components. To apply a default layout to content, see . +:::moniker range=">= aspnetcore-8.0" + +> [!IMPORTANT] +> Blazor Web Apps don't use the parameter (`...` 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 . + +:::moniker-end + ## Route to components from multiple assemblies :::moniker range=">= aspnetcore-8.0" diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md index 077b8721bcdb..93d9ef05776a 100644 --- a/aspnetcore/blazor/security/index.md +++ b/aspnetcore/blazor/security/index.md @@ -409,6 +409,12 @@ You can also supply different content for display if the user isn't authorized w A default event handler for an authorized element, such as the `SecureMethod` method for the `