From 042e9f2fa037b74aaacf6561c5275c3c3d333a56 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:29:56 -0400 Subject: [PATCH 1/8] Blazor support to an ASP.NET Core app (Part 2) --- aspnetcore/blazor/components/integration.md | 191 +++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index ab1ca2930162..3421d2040e0b 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -32,7 +32,7 @@ This section covers adding Blazor support to an ASP.NET Core app: * [Add static server Razor component rendering](#add-static-server-razor-component-rendering) * [Enable interactive server rendering](#enable-interactive-server-rendering) - +* [Enable interactive Auto or WebAssembly rendering](#enable-interactive-auto-or-webassembly-rendering) > [!NOTE] > For the examples in this section, the example app's name and namespace is `AspNetCoreApp`. @@ -188,7 +188,196 @@ Add a `Counter` component to the app with the interactive server render mode. When the app is run, the `Counter` component is accessed at the `/counter` endpoint. +### Enable interactive Auto or WebAssembly rendering +1. Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server) NuGet package to the app. + + [!INCLUDE[](~/includes/package-reference.md)] + + + +1. Create a donor Blazor Web App, which will provide assets to the app. Follow the guidance in the article, selecting support for the following template features when generating the Blazor Web App. + + > [!IMPORTANT] + > For the app's name, use the same name as the ASP.NET Core app, which results in matching app name markup in components and matching namespaces in code. Using the same name/namespace isn't strictly required, as namespaces can be adjusted after assets are moved from the donor app to the ASP.NET Core app. However, time is saved by matching the namespaces at the outset, so that assets can be moved from the donor app to the ASP.NET Core app and used without spending time making manual namespace adjustments. + + * For **Interactivity type**, select **Auto (Server and WebAssembly)** for Visual Studio or use the `-int Auto` option if using the .NET CLI. + * Set the **Interactivity location** to **Per page/component** for Visual Studio or ***avoid*** using the `-ai|--all-interactive` option when using the .NET CLI. + +1. From the donor Blazor Web App, copy Bootstrap and Blazor styles into the ASP.NET Core project's `wwwroot` folder: + + * `wwwroot/bootstrap` folder + * `app.css` + +1. From the donor Blazor Web App, copy the entire `.Client` project into the solution folder of the ASP.NET Core app. + + > [!IMPORTANT] + > **Don't copy the `.Client` folder into the ASP.NET Core project's folder.** The best approach for organizing .NET solutions is to place each project of the solution into its own folder inside of a top-level solution folder. If a solution folder above the ASP.NET Core project's folder doesn't exist, create one. Next, copy the `.Client` project's folder from the donor Blazor Web App into the solution folder. The final project folder structure should have the following layout: + > + > * `AspNetCoreAppSolution` (top-level solution folder) + > * `AspNetCoreApp` (original ASP.NET Core project) + > * `AspNetCoreApp.Client` (`.Client` project folder from the donor Blazor Web App) + > + > For the ASP.NET Core solution file, you can leave it in the ASP.NET Core project's folder. Alternatively, you can move the solution file or create a new one in the top-level solution folder as long as the project references correctly point to the project files (`.csproj`) of the two projects in the solution folder. + +1. From the donor Blazor Web App, copy the entire `Components` folder into the ASP.NET Core project folder. + +1. In the ASP.NET Core project's `Components` folder, delete the following components from the `Components/Pages` folder: + + * `Home` component (`Home.razor`) + * `Weather` component (`Weather.razor`) + +1. If you named the donor Blazor Web App when you created the donor project the same as the ASP.NET Core app, the namespaces used by the donated assets match those in the ASP.NET Core app. You shouldn't need to take further steps to match namespaces. If you used a different namespace when creating the donor Blazor Web App project, you must adjust the namespaces across the donated assets to match if you intend to use the rest of this guidance exactly as presented. If the namespaces don't match, ***either*** adjust the namespaces before proceeding ***or*** adjust the namespaces as you following the remaining guidance in this section. + +1. Delete the donor Blazor Web App, as it has no further use in this process. + +1. Add the `.Client` project to the solution: + + In Visual Studio, right-click the solution in **Solution Explorer** and select **Add** > **Existing Project**. Navigate to the `.Client` folder and select the project file (`.csproj`). + + If using the .NET CLI, use the [`dotnet sln add` command](/dotnet/core/tools/dotnet-sln#add) to add the `.Client` project to the solution. + +1. Add a project reference to the ASP.NET Core project for the client project: + + In Visual Studio, right-click the ASP.NET Core project and select **Add** > **Project Reference**. Select the `.Client` project and select **OK**. + + If using the .NET CLI, from the ASP.NET Core project's folder, use the following command: + + ```dotnetcli + dotnet add reference ../AspNetCoreApp.Client/AspNetCoreApp.Client.csproj + ``` + + > [!NOTE] + > The preceding command assumes the following: + > + > * The project file name is `AspNetCoreApp.Client.csproj`. + > * The `.Client` project is in a `AspNetCoreApp.Client` folder inside the solution folder. The `.Client` folder is side-by-side with the ASP.NET Core project's folder. + > + > For more information on the `dotnet add reference` command, see [`dotnet add reference` (.NET documentation)](/dotnet/core/tools/dotnet-add-reference). + +1. In the ASP.NET Core project's `Program` file, add a `using` statement to the top of the file for the project's components: + + ```csharp + using AspNetCoreApp.Components; + ``` + + Add the interactive component services (`AddInteractiveServerComponents` and `AddInteractiveWebAssemblyComponents`) with Razor component services (`AddRazorComponents`) before the app is built (the line that calls `builder.Build()`): + + ```csharp + builder.Services.AddRazorComponents() + .AddInteractiveServerComponents() + .AddInteractiveWebAssemblyComponents(); + ``` + + Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline after the call to `app.UseRouting`. If there are calls to `app.UseRouting` and `app.UseEndpoints`, the call to `app.UseAntiforgery` must go between them. A call to `app.UseAntiforgery` must be placed after calls to `app.UseAuthentication` and `app.UseAuthorization`. + + ```csharp + app.UseAntiforgery(); + ``` + + Add the interactive render modes (`AddInteractiveServerRenderMode` and `AddInteractiveWebAssemblyRenderMode`) and additional assemblies for the `.Client` project with `MapRazorComponents` before the app is run (the line that calls `app.Run`): + + ```csharp + app.MapRazorComponents() + .AddInteractiveServerRenderMode() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(typeof(AspNetCoreApp.Client._Imports).Assembly); + ``` + +1. As you add Razor components to the solution, either in the ASP.NET Core project or the `.Client` project, configure the render mode of each component. + + The donor Blazor Web App supplies a `Counter` component to the solution (`Pages/Counter.razor` in the `AspNetCoreApp.Client` project), which can be used for development testing. + + Notice that the `Counter` component in the `.Client` project adopts the Auto render mode either using the `@attribute` ***or*** `@rendermode` directive: + + ```razor + @attribute [RenderModeInteractiveAuto] + ``` + + ```razor + @rendermode InteractiveAuto + ``` + + For any of your ASP.NET Core app components that should also adopt the Auto render mode, place them in the `.Client` project's `Pages` folder (or `Shared` folder for non-routable, shared components) and provide the routable components in the `Pages` folder with ***either*** of the preceding directives, noting that a shared component typically inherits its render mode and doesn't require a directive. + + Such components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto render mode. + + To further test in development with an interactive server `Counter` component, make a copy of the `Client` project's `Counter` component and change its file name to `Counter2.razor`. Place the file in the ASP.NET Core app (`Pages/Counter2.razor` in the `AspNetCoreApp` project). + + Open the `Counter2.razor` file and change the route to avoid a conflict with the existing `Counter` component: + + ```diff + - @page "/counter" + + @page "/counter-2" + ``` + + Change the interactive render mode using ***either*** of the following lines: + + ```razor + @attribute [RenderModeInteractiveServer] + ``` + + ```razor + @rendermode InteractiveServer + ``` + + Change the page title and heading markup to reflect that this is the 2nd counter component in the app: + + ```razor + Counter 2 + +

Counter 2

+ ``` + + Add the `Counter2` component to the `NavMenu` component (`Pages/Layout/NavMenu.razor`): + + ```razor + + ``` + + Remove the `Weather` component navigation menu entry from the `NavMenu` component: + + ```diff + - + ``` + + For components that should also strictly adopt the interactive server render mode, add ***either*** of the preceding directives to them and leave them in the ASP.NET Core project's `Pages`/`Shared` folders. Such components only ever render on the server. Component code is kept private on the server using the interactive server render mode. + + When the app is run in the next step, navigate to each of the counter components (`/counter` and `/counter-2`) to inspect how they render. + + If any of your server-side components should also disable prerendering, see . + + For any components that should strictly adopt the interactive WebAssembly render mode in the `.Client` project (`Pages` folder of the `AspNetCoreApp.Client` project), explicitly configure the render mode: + + ```razor + @attribute [RenderModeInteractiveWebAssembly] + ``` + + ```razor + @rendermode InteractiveWebAssembly + ``` + + Such components only render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the interactive WebAssembly render mode. + + For additional information on applying render modes to components, see . + +1. Run the solution from the ***ASP.NET Core app*** project: + + For Visual Studio, confirm that the ASP.NET Core project is selected in **Solution Explorer** when running the app. + + If using the .NET CLI, run the project from the ASP.NET Core project's folder. + + For the `Counter` component of the `.Client` project, navigate to `/counter`. + + If you added the `Counter2` component, which is strictly configured for interactive server rendering, navigate to `/counter-2`. ## Use non-routable components in pages or views From 05eddd27ba5c769cffb54c99a51dcaf541b817e6 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Mon, 23 Oct 2023 08:57:02 -0400 Subject: [PATCH 2/8] Updates --- aspnetcore/blazor/components/integration.md | 315 +++++++++----------- 1 file changed, 138 insertions(+), 177 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 3421d2040e0b..dcbac2dcc4a0 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -39,7 +39,9 @@ This section covers adding Blazor support to an ASP.NET Core app: ### Add static server Razor component rendering -Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's namespace as each file is added. +Add a `Components` folder to the app. + +Add the following `_Imports` file for namespaces used by Razor components. `Components/_Imports.razor`: @@ -52,10 +54,14 @@ Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's @using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop -@using {APP NAMESPACE} -@using {APP NAMESPACE}.Components +@using AspNetCoreApp +@using AspNetCoreApp.Components ``` +Change the namespace `AspNetCoreApp` in the preceding example to match the app. + +Add the Blazor router (``) to the app in a `Routes` component, which is placed in the app's `Components` folder. + `Components/Routes.razor`: ```razor @@ -75,6 +81,8 @@ You can supply a default layout with the . +Add an `App` component to the app, which serves as the root component for other components. + `Components/App.razor`: ```razor @@ -85,7 +93,7 @@ For more information, see - + @@ -97,6 +105,16 @@ For more information, see ``` +For the `` element in the preceding example, change `AspNetCoreApp` in the stylesheet's file name to match the app's namespace. For example, an app with the namespace `ContosoApp` uses the `ContosoApp.styles.css` stylesheet file name: + +```html + +``` + +Add a `Pages` folder to the `Components` folder to hold routable Razor components. + +Add the following `Welcome` component to demonstrate static server rendering. + `Components/Pages/Welcome.razor`: ```razor @@ -114,29 +132,33 @@ For more information, see (); -``` + ```csharp + app.UseAntiforgery(); + ``` + +* Add `MapRazorComponents` to the app's request processing pipeline with the `App` component (`App.razor`) specified as the default root component. Place the following code before the the line that calls `app.Run`: + + ```csharp + app.MapRazorComponents(); + ``` When the app is run, the `Welcome` component is accessed at the `/welcome` endpoint. @@ -144,23 +166,23 @@ When the app is run, the `Welcome` component is accessed at the `/welcome` endpo Follow the guidance in the [Add static server Razor component rendering](#add-static-server-razor-component-rendering) section. -Make the following changes in the app's `Program` file. +Make the following changes in the app's `Program` file: -Add a call to `AddInteractiveServerComponents` where Razor component services are added with `AddRazorComponents`: +* Add a call to `AddInteractiveServerComponents` where Razor component services are added with `AddRazorComponents`: -```csharp -builder.Services.AddRazorComponents() - .AddInteractiveServerComponents(); -``` + ```csharp + builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + ``` -Add a call to `AddInteractiveServerRenderMode` where Razor components are mapped with `MapRazorComponents`: +* Add a call to `AddInteractiveServerRenderMode` where Razor components are mapped with `MapRazorComponents`: -```csharp -app.MapRazorComponents() - .AddInteractiveServerRenderMode(); -``` + ```csharp + app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + ``` -Add a `Counter` component to the app with the interactive server render mode. +Add the following `Counter` component to the app that adopts the interactive server render mode. `Components/Pages/Counter.razor`: @@ -186,198 +208,137 @@ Add a `Counter` component to the app with the interactive server render mode. } ``` -When the app is run, the `Counter` component is accessed at the `/counter` endpoint. - -### Enable interactive Auto or WebAssembly rendering - -1. Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server) NuGet package to the app. - - [!INCLUDE[](~/includes/package-reference.md)] - - - -1. Create a donor Blazor Web App, which will provide assets to the app. Follow the guidance in the article, selecting support for the following template features when generating the Blazor Web App. - - > [!IMPORTANT] - > For the app's name, use the same name as the ASP.NET Core app, which results in matching app name markup in components and matching namespaces in code. Using the same name/namespace isn't strictly required, as namespaces can be adjusted after assets are moved from the donor app to the ASP.NET Core app. However, time is saved by matching the namespaces at the outset, so that assets can be moved from the donor app to the ASP.NET Core app and used without spending time making manual namespace adjustments. +When the app is run, the `Counter` component is accessed at `/counter`. - * For **Interactivity type**, select **Auto (Server and WebAssembly)** for Visual Studio or use the `-int Auto` option if using the .NET CLI. - * Set the **Interactivity location** to **Per page/component** for Visual Studio or ***avoid*** using the `-ai|--all-interactive` option when using the .NET CLI. +### Enable interactive Auto and WebAssembly rendering -1. From the donor Blazor Web App, copy Bootstrap and Blazor styles into the ASP.NET Core project's `wwwroot` folder: +Follow the guidance in the following sections to enable static and interactive server rendering: - * `wwwroot/bootstrap` folder - * `app.css` +* [Add static server Razor component rendering](#add-static-server-razor-component-rendering) +* [Enable interactive server rendering](#enable-interactive-server-rendering) -1. From the donor Blazor Web App, copy the entire `.Client` project into the solution folder of the ASP.NET Core app. +Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server) NuGet package to the app. - > [!IMPORTANT] - > **Don't copy the `.Client` folder into the ASP.NET Core project's folder.** The best approach for organizing .NET solutions is to place each project of the solution into its own folder inside of a top-level solution folder. If a solution folder above the ASP.NET Core project's folder doesn't exist, create one. Next, copy the `.Client` project's folder from the donor Blazor Web App into the solution folder. The final project folder structure should have the following layout: - > - > * `AspNetCoreAppSolution` (top-level solution folder) - > * `AspNetCoreApp` (original ASP.NET Core project) - > * `AspNetCoreApp.Client` (`.Client` project folder from the donor Blazor Web App) - > - > For the ASP.NET Core solution file, you can leave it in the ASP.NET Core project's folder. Alternatively, you can move the solution file or create a new one in the top-level solution folder as long as the project references correctly point to the project files (`.csproj`) of the two projects in the solution folder. +[!INCLUDE[](~/includes/package-reference.md)] -1. From the donor Blazor Web App, copy the entire `Components` folder into the ASP.NET Core project folder. + -1. In the ASP.NET Core project's `Components` folder, delete the following components from the `Components/Pages` folder: +Create a donor Blazor Web App to provide assets to the app. Follow the guidance in the article, selecting support for the following template features when generating the Blazor Web App. - * `Home` component (`Home.razor`) - * `Weather` component (`Weather.razor`) +For the app's name, use the same name as the ASP.NET Core app, which results in matching app name markup in components and matching namespaces in code. Using the same name/namespace isn't strictly required, as namespaces can be adjusted after assets are moved from the donor app to the ASP.NET Core app. However, time is saved by matching the namespaces at the outset. -1. If you named the donor Blazor Web App when you created the donor project the same as the ASP.NET Core app, the namespaces used by the donated assets match those in the ASP.NET Core app. You shouldn't need to take further steps to match namespaces. If you used a different namespace when creating the donor Blazor Web App project, you must adjust the namespaces across the donated assets to match if you intend to use the rest of this guidance exactly as presented. If the namespaces don't match, ***either*** adjust the namespaces before proceeding ***or*** adjust the namespaces as you following the remaining guidance in this section. +Visual Studio: -1. Delete the donor Blazor Web App, as it has no further use in this process. +* For **Interactivity type**, select **Auto (Server and WebAssembly)**. +* Set the **Interactivity location** to **Per page/component**. +* Deselect the checkbox for **Include sample pages**. -1. Add the `.Client` project to the solution: +.NET CLI: - In Visual Studio, right-click the solution in **Solution Explorer** and select **Add** > **Existing Project**. Navigate to the `.Client` folder and select the project file (`.csproj`). +* Use the `-int Auto` option. +* Do ***not*** use the `-ai|--all-interactive` option. +* Pass the `-e|--empty` option. - If using the .NET CLI, use the [`dotnet sln add` command](/dotnet/core/tools/dotnet-sln#add) to add the `.Client` project to the solution. +From the donor Blazor Web App, copy the entire `.Client` project into the solution folder of the ASP.NET Core app. -1. Add a project reference to the ASP.NET Core project for the client project: +> [!IMPORTANT] +> **Don't copy the `.Client` folder into the ASP.NET Core project's folder.** The best approach for organizing .NET solutions is to place each project of the solution into its own folder inside of a top-level solution folder. If a solution folder above the ASP.NET Core project's folder doesn't exist, create one. Next, copy the `.Client` project's folder from the donor Blazor Web App into the solution folder. The final project folder structure should have the following layout: +> +> * `AspNetCoreAppSolution` (top-level solution folder) +> * `AspNetCoreApp` (original ASP.NET Core project) +> * `AspNetCoreApp.Client` (`.Client` project folder from the donor Blazor Web App) +> +> For the ASP.NET Core solution file, you can leave it in the ASP.NET Core project's folder. Alternatively, you can move the solution file or create a new one in the top-level solution folder as long as the project references correctly point to the project files (`.csproj`) of the two projects in the solution folder. - In Visual Studio, right-click the ASP.NET Core project and select **Add** > **Project Reference**. Select the `.Client` project and select **OK**. +From the donor Blazor Web App, copy the `Components` folder into the ASP.NET Core app's project folder. - If using the .NET CLI, from the ASP.NET Core project's folder, use the following command: +In the ASP.NET Core project's `Components/Pages` folder, delete the `Home` component (`Home.razor`). - ```dotnetcli - dotnet add reference ../AspNetCoreApp.Client/AspNetCoreApp.Client.csproj - ``` +If you named the donor Blazor Web App when you created the donor project the same as the ASP.NET Core app, the namespaces used by the donated assets match those in the ASP.NET Core app. You shouldn't need to take further steps to match namespaces. If you used a different namespace when creating the donor Blazor Web App project, you must adjust the namespaces across the donated assets to match if you intend to use the rest of this guidance exactly as presented. If the namespaces don't match, ***either*** adjust the namespaces before proceeding ***or*** adjust the namespaces as you follow the remaining guidance in this section. - > [!NOTE] - > The preceding command assumes the following: - > - > * The project file name is `AspNetCoreApp.Client.csproj`. - > * The `.Client` project is in a `AspNetCoreApp.Client` folder inside the solution folder. The `.Client` folder is side-by-side with the ASP.NET Core project's folder. - > - > For more information on the `dotnet add reference` command, see [`dotnet add reference` (.NET documentation)](/dotnet/core/tools/dotnet-add-reference). +Delete the donor Blazor Web App, as it has no further use in this process. -1. In the ASP.NET Core project's `Program` file, add a `using` statement to the top of the file for the project's components: +Add the `.Client` project to the solution: - ```csharp - using AspNetCoreApp.Components; - ``` +* Visual Studio: Right-click the solution in **Solution Explorer** and select **Add** > **Existing Project**. Navigate to the `.Client` folder and select the project file (`.csproj`). - Add the interactive component services (`AddInteractiveServerComponents` and `AddInteractiveWebAssemblyComponents`) with Razor component services (`AddRazorComponents`) before the app is built (the line that calls `builder.Build()`): +* .NET CLI: Use the [`dotnet sln add` command](/dotnet/core/tools/dotnet-sln#add) to add the `.Client` project to the solution. - ```csharp - builder.Services.AddRazorComponents() - .AddInteractiveServerComponents() - .AddInteractiveWebAssemblyComponents(); - ``` +Add a project reference to the ASP.NET Core project for the client project: - Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline after the call to `app.UseRouting`. If there are calls to `app.UseRouting` and `app.UseEndpoints`, the call to `app.UseAntiforgery` must go between them. A call to `app.UseAntiforgery` must be placed after calls to `app.UseAuthentication` and `app.UseAuthorization`. +* Visual Studio: Right-click the ASP.NET Core project and select **Add** > **Project Reference**. Select the `.Client` project and select **OK**. - ```csharp - app.UseAntiforgery(); - ``` +* .NET CLI: From the ASP.NET Core project's folder, use the following command: - Add the interactive render modes (`AddInteractiveServerRenderMode` and `AddInteractiveWebAssemblyRenderMode`) and additional assemblies for the `.Client` project with `MapRazorComponents` before the app is run (the line that calls `app.Run`): - - ```csharp - app.MapRazorComponents() - .AddInteractiveServerRenderMode() - .AddInteractiveWebAssemblyRenderMode() - .AddAdditionalAssemblies(typeof(AspNetCoreApp.Client._Imports).Assembly); - ``` - -1. As you add Razor components to the solution, either in the ASP.NET Core project or the `.Client` project, configure the render mode of each component. - - The donor Blazor Web App supplies a `Counter` component to the solution (`Pages/Counter.razor` in the `AspNetCoreApp.Client` project), which can be used for development testing. - - Notice that the `Counter` component in the `.Client` project adopts the Auto render mode either using the `@attribute` ***or*** `@rendermode` directive: - - ```razor - @attribute [RenderModeInteractiveAuto] - ``` + ```dotnetcli + dotnet add reference ../AspNetCoreApp.Client/AspNetCoreApp.Client.csproj + ``` - ```razor - @rendermode InteractiveAuto - ``` + The preceding command assumes the following: + + * The project file name is `AspNetCoreApp.Client.csproj`. + * The `.Client` project is in a `AspNetCoreApp.Client` folder inside the solution folder. The `.Client` folder is side-by-side with the ASP.NET Core project's folder. + + For more information on the `dotnet add reference` command, see [`dotnet add reference` (.NET documentation)](/dotnet/core/tools/dotnet-add-reference). - For any of your ASP.NET Core app components that should also adopt the Auto render mode, place them in the `.Client` project's `Pages` folder (or `Shared` folder for non-routable, shared components) and provide the routable components in the `Pages` folder with ***either*** of the preceding directives, noting that a shared component typically inherits its render mode and doesn't require a directive. - - Such components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto render mode. - - To further test in development with an interactive server `Counter` component, make a copy of the `Client` project's `Counter` component and change its file name to `Counter2.razor`. Place the file in the ASP.NET Core app (`Pages/Counter2.razor` in the `AspNetCoreApp` project). - - Open the `Counter2.razor` file and change the route to avoid a conflict with the existing `Counter` component: - - ```diff - - @page "/counter" - + @page "/counter-2" - ``` +Make the following changes to the ASP.NET Core app's `Program` file: - Change the interactive render mode using ***either*** of the following lines: - - ```razor - @attribute [RenderModeInteractiveServer] - ``` +* Add interactive WebAssembly component services with `AddInteractiveWebAssemblyComponents` where Razor component services are added with `AddRazorComponents`: - ```razor - @rendermode InteractiveServer - ``` + ```csharp + builder.Services.AddRazorComponents() + .AddInteractiveServerComponents() + .AddInteractiveWebAssemblyComponents(); + ``` - Change the page title and heading markup to reflect that this is the 2nd counter component in the app: +* Add the interactive WebAssembly render mode (`AddInteractiveWebAssemblyRenderMode`) and additional assemblies for the `.Client` project where Razor components are mapped with `MapRazorComponents`: - ```razor - Counter 2 + ```csharp + app.MapRazorComponents() + .AddInteractiveServerRenderMode() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(typeof(AspNetCoreApp.Client._Imports).Assembly); + ``` -

Counter 2

- ``` + In the preceding example, change `AspNetCoreApp.Client` to match the `.Client` project's namespace. - Add the `Counter2` component to the `NavMenu` component (`Pages/Layout/NavMenu.razor`): +Add a `Components` folder and a `Components/Pages` folder to the `.Client` project. - ```razor - - ``` +To demonstrate the interactive Auto render mode, add the following `Counter` component to the `.Client` project. - Remove the `Weather` component navigation menu entry from the `NavMenu` component: +`Components/Pages/Counter.razor` in the `.Client` project: - ```diff - - - ``` +```razor +@page "/counter" +@rendermode InteractiveAuto - For components that should also strictly adopt the interactive server render mode, add ***either*** of the preceding directives to them and leave them in the ASP.NET Core project's `Pages`/`Shared` folders. Such components only ever render on the server. Component code is kept private on the server using the interactive server render mode. +Counter - When the app is run in the next step, navigate to each of the counter components (`/counter` and `/counter-2`) to inspect how they render. - - If any of your server-side components should also disable prerendering, see . +

Counter

- For any components that should strictly adopt the interactive WebAssembly render mode in the `.Client` project (`Pages` folder of the `AspNetCoreApp.Client` project), explicitly configure the render mode: +

Current count: @currentCount

- ```razor - @attribute [RenderModeInteractiveWebAssembly] - ``` + - ```razor - @rendermode InteractiveWebAssembly - ``` +@code { + private int currentCount = 0; - Such components only render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the interactive WebAssembly render mode. + private void IncrementCount() + { + currentCount++; + } +} +``` - For additional information on applying render modes to components, see . +Auto render mode components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto render mode. For more information, see . -1. Run the solution from the ***ASP.NET Core app*** project: +Run the solution from the ***ASP.NET Core app*** project: - For Visual Studio, confirm that the ASP.NET Core project is selected in **Solution Explorer** when running the app. - - If using the .NET CLI, run the project from the ASP.NET Core project's folder. +* Visual Studio: Confirm that the ASP.NET Core project is selected in **Solution Explorer** when running the app. - For the `Counter` component of the `.Client` project, navigate to `/counter`. +* .NET CLI: Run the project from the ASP.NET Core project's folder. - If you added the `Counter2` component, which is strictly configured for interactive server rendering, navigate to `/counter-2`. +To load the `Counter` component, navigate to `/counter`. ## Use non-routable components in pages or views From 79f486eebf64b8438aef22d66aa2bebd05683190 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Mon, 23 Oct 2023 09:03:26 -0400 Subject: [PATCH 3/8] Updates --- aspnetcore/blazor/components/integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index dcbac2dcc4a0..bd3fc3f5f26a 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -32,7 +32,7 @@ This section covers adding Blazor support to an ASP.NET Core app: * [Add static server Razor component rendering](#add-static-server-razor-component-rendering) * [Enable interactive server rendering](#enable-interactive-server-rendering) -* [Enable interactive Auto or WebAssembly rendering](#enable-interactive-auto-or-webassembly-rendering) +* [Enable interactive Auto or WebAssembly rendering](#enable-interactive-auto-and-webassembly-rendering) > [!NOTE] > For the examples in this section, the example app's name and namespace is `AspNetCoreApp`. From 800d7b65c8856f98a63f317d3d16e4bbec2d3b00 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 24 Oct 2023 04:18:09 -0400 Subject: [PATCH 4/8] Updates --- aspnetcore/blazor/components/integration.md | 47 ++++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index bd3fc3f5f26a..58e44a702b83 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -210,12 +210,16 @@ Add the following `Counter` component to the app that adopts the interactive ser When the app is run, the `Counter` component is accessed at `/counter`. -### Enable interactive Auto and WebAssembly rendering +### Enable interactive Auto or WebAssembly rendering -Follow the guidance in the following sections to enable static and interactive server rendering: +Follow the guidance in the [Add static server Razor component rendering](#add-static-server-razor-component-rendering) section. -* [Add static server Razor component rendering](#add-static-server-razor-component-rendering) -* [Enable interactive server rendering](#enable-interactive-server-rendering) +Auto render mode components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. The interactive WebAssembly render mode renders only renders components on the client after the Blazor bundle is downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto or WebAssembly render modes. For more information, see . + +After deciding which render mode to adopt: + +* If you plan to adopt the Auto render mode, follow the guidance in the [Enable interactive server rendering](#enable-interactive-server-rendering) section. +* If you plan to only adopt interactive WebAssembly rendering, continue without adding interactive server rendering. Add a package reference for the [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server) NuGet package to the app. @@ -283,7 +287,9 @@ Add a project reference to the ASP.NET Core project for the client project: Make the following changes to the ASP.NET Core app's `Program` file: -* Add interactive WebAssembly component services with `AddInteractiveWebAssemblyComponents` where Razor component services are added with `AddRazorComponents`: +* Add interactive WebAssembly component services with `AddInteractiveWebAssemblyComponents` where Razor component services are added with `AddRazorComponents`. + + For interactive Auto rendering: ```csharp builder.Services.AddRazorComponents() @@ -291,7 +297,16 @@ Make the following changes to the ASP.NET Core app's `Program` file: .AddInteractiveWebAssemblyComponents(); ``` -* Add the interactive WebAssembly render mode (`AddInteractiveWebAssemblyRenderMode`) and additional assemblies for the `.Client` project where Razor components are mapped with `MapRazorComponents`: + For only interactive WebAssembly rendering: + + ```csharp + builder.Services.AddRazorComponents() + .AddInteractiveWebAssemblyComponents(); + ``` + +* Add the interactive WebAssembly render mode (`AddInteractiveWebAssemblyRenderMode`) and additional assemblies for the `.Client` project where Razor components are mapped with `MapRazorComponents`. + + For interactive Auto rendering: ```csharp app.MapRazorComponents() @@ -300,13 +315,19 @@ Make the following changes to the ASP.NET Core app's `Program` file: .AddAdditionalAssemblies(typeof(AspNetCoreApp.Client._Imports).Assembly); ``` - In the preceding example, change `AspNetCoreApp.Client` to match the `.Client` project's namespace. + For only interactive WebAssembly rendering: -Add a `Components` folder and a `Components/Pages` folder to the `.Client` project. + ```csharp + app.MapRazorComponents() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(typeof(AspNetCoreApp.Client._Imports).Assembly); + ``` + + In the preceding examples, change `AspNetCoreApp.Client` to match the `.Client` project's namespace. -To demonstrate the interactive Auto render mode, add the following `Counter` component to the `.Client` project. +Add a `Components` folder and a `Components/Pages` folder to the `.Client` project. -`Components/Pages/Counter.razor` in the `.Client` project: +Add the following `Counter` component (`Components/Pages/Counter.razor`) to the `.Client` project: ```razor @page "/counter" @@ -330,7 +351,11 @@ To demonstrate the interactive Auto render mode, add the following `Counter` com } ``` -Auto render mode components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto render mode. For more information, see . +If the app is only adopting interactive WebAssembly rendering, remove the `@rendermode` directive and value: + +```diff +- @rendermode InteractiveAuto +``` Run the solution from the ***ASP.NET Core app*** project: From 08f45ff8758f92de3c333895f72b9bff1889bd2f Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 24 Oct 2023 04:54:51 -0400 Subject: [PATCH 5/8] Updates --- aspnetcore/blazor/components/integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 58e44a702b83..986db7cde343 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -210,7 +210,7 @@ Add the following `Counter` component to the app that adopts the interactive ser When the app is run, the `Counter` component is accessed at `/counter`. -### Enable interactive Auto or WebAssembly rendering +### Enable interactive Auto and WebAssembly rendering Follow the guidance in the [Add static server Razor component rendering](#add-static-server-razor-component-rendering) section. From f2171e136b83680df96d6eab3f9b918c4db7cf19 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:32:27 -0400 Subject: [PATCH 6/8] Update aspnetcore/blazor/components/integration.md Co-authored-by: Daniel Roth --- aspnetcore/blazor/components/integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 986db7cde343..eae909e13b5b 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -105,7 +105,7 @@ Add an `App` component to the app, which serves as the root component for other ``` -For the `` element in the preceding example, change `AspNetCoreApp` in the stylesheet's file name to match the app's namespace. For example, an app with the namespace `ContosoApp` uses the `ContosoApp.styles.css` stylesheet file name: +For the `` element in the preceding example, change `AspNetCoreApp` in the stylesheet's file name to match the app's project name. For example, a project named `ContosoApp` uses the `ContosoApp.styles.css` stylesheet file name: ```html From 518729ccc8bb5be5ea8117280c53089ac2865068 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:03:12 -0400 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Daniel Roth --- aspnetcore/blazor/components/integration.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index eae909e13b5b..b679dbff6492 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -214,7 +214,7 @@ When the app is run, the `Counter` component is accessed at `/counter`. Follow the guidance in the [Add static server Razor component rendering](#add-static-server-razor-component-rendering) section. -Auto render mode components render on the server first, then render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. The interactive WebAssembly render mode renders only renders components on the client after the Blazor bundle is downloaded and the Blazor runtime activates. Keep in mind that component code is ***not*** private using the Auto or WebAssembly render modes. For more information, see . +Components using the Auto render mode initially use interactive server rendering, but then switch to render on the client after the Blazor bundle has been downloaded and the Blazor runtime activates. Components using the WebAssembly render mode only render interactively on the client after the Blazor bundle is downloaded and the Blazor runtime activates. Keep in mind that when using the Auto or WebAssembly render modes, component code downloaded to the client is ***not*** private. For more information, see . After deciding which render mode to adopt: @@ -254,10 +254,6 @@ From the donor Blazor Web App, copy the entire `.Client` project into the soluti > > For the ASP.NET Core solution file, you can leave it in the ASP.NET Core project's folder. Alternatively, you can move the solution file or create a new one in the top-level solution folder as long as the project references correctly point to the project files (`.csproj`) of the two projects in the solution folder. -From the donor Blazor Web App, copy the `Components` folder into the ASP.NET Core app's project folder. - -In the ASP.NET Core project's `Components/Pages` folder, delete the `Home` component (`Home.razor`). - If you named the donor Blazor Web App when you created the donor project the same as the ASP.NET Core app, the namespaces used by the donated assets match those in the ASP.NET Core app. You shouldn't need to take further steps to match namespaces. If you used a different namespace when creating the donor Blazor Web App project, you must adjust the namespaces across the donated assets to match if you intend to use the rest of this guidance exactly as presented. If the namespaces don't match, ***either*** adjust the namespaces before proceeding ***or*** adjust the namespaces as you follow the remaining guidance in this section. Delete the donor Blazor Web App, as it has no further use in this process. @@ -268,7 +264,7 @@ Add the `.Client` project to the solution: * .NET CLI: Use the [`dotnet sln add` command](/dotnet/core/tools/dotnet-sln#add) to add the `.Client` project to the solution. -Add a project reference to the ASP.NET Core project for the client project: +Add a project reference from the ASP.NET Core project to the client project: * Visual Studio: Right-click the ASP.NET Core project and select **Add** > **Project Reference**. Select the `.Client` project and select **OK**. @@ -325,9 +321,9 @@ Make the following changes to the ASP.NET Core app's `Program` file: In the preceding examples, change `AspNetCoreApp.Client` to match the `.Client` project's namespace. -Add a `Components` folder and a `Components/Pages` folder to the `.Client` project. +Add a `Pages` folder to the `.Client` project. -Add the following `Counter` component (`Components/Pages/Counter.razor`) to the `.Client` project: +Add the following `Counter` component (`Pages/Counter.razor`) to the `.Client` project: ```razor @page "/counter" From 668c5126dc5d9c50e73a1ad1f40864187d7ebb12 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:07:51 -0400 Subject: [PATCH 8/8] Updates --- aspnetcore/blazor/components/integration.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index b679dbff6492..86ef9d242fd0 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -323,7 +323,12 @@ Make the following changes to the ASP.NET Core app's `Program` file: Add a `Pages` folder to the `.Client` project. -Add the following `Counter` component (`Pages/Counter.razor`) to the `.Client` project: +If the ASP.NET Core project has an existing `Counter` component: + +* Move the component to the `Pages` folder of the `.Client` project. +* Remove the `@rendermode` directive at the top of the component file. + +If the ASP.NET Core app doesn't have a `Counter` component, add the following `Counter` component (`Pages/Counter.razor`) to the `.Client` project: ```razor @page "/counter"