From 718adaae7a6129d0d17989f469b4a347782e034e Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 07:35:26 -0400 Subject: [PATCH 1/8] Add Blazor support to an ASP.NET Core app --- aspnetcore/blazor/components/integration.md | 32 +++++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 8da12d79a4b4..fe4ed33e776f 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -22,19 +22,41 @@ Razor components can be integrated into Razor Pages, MVC, and other types of ASP Use the guidance in the following sections depending on the project's requirements: - +* Blazor support can be [added to an ASP.NET Core app](#add-blazor-support-to-an-aspnet-core-app). * For interactive components that aren't directly routable from user requests, see the [Use non-routable components in pages or views](#use-non-routable-components-in-pages-or-views) section. Follow this guidance when the app embeds components into existing pages and views with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper). * For interactive components that are directly routable from user requests, see the [Use routable components](#use-routable-components) section. Follow this guidance when visitors should be able to make an HTTP request in their browser for a component with an [`@page`](xref:mvc/views/razor#page) directive. - - ## Use non-routable components in pages or views Use the following guidance to integrate Razor components into pages and views of an existing Razor Pages or MVC app with the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper). From 9829e05a3f79755a93806fe2aa16463668949e5e Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:32:43 -0400 Subject: [PATCH 2/8] Updates --- aspnetcore/blazor/components/integration.md | 93 ++++++++++++++++++++- 1 file changed, 89 insertions(+), 4 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index fe4ed33e776f..2a92145a37f8 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -39,21 +39,106 @@ This section covers adding Blazor support to an ASP.NET Core app: ### Add static server Razor component rendering -No donor needed ... just show the minimal API changes and additions required. +Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's namespace as each file is added. +`Components/_Imports.razor`: + +```razor +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using {APP NAMESPACE} +@using {APP NAMESPACE}.Components +``` + +`Components/Routes.razor`: +```razor + + + + + + +``` +`Components/App.razor`: +```razor + + + + + + + + + + + + -### Enable interactive server rendering + + + + + + +``` + +`Components/Pages/Welcome.razor`: + +```razor +@page "/welcome" + +Welcome! + +

Welcome to Blazor!

+ +

@message

+ +@code { + private string message = + "Hello from a Razor component and welcome to Blazor!"; +} +``` + +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 {APP NAMESPACE}.Components; +``` + +Add Razor component services (`AddRazorComponents`) before the app is built (the line that calls `builder.Build()`): + +```csharp +builder.Services.AddRazorComponents(); +``` -No donor needed ... just minimal changes. +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 `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 app is run (the line that calls `app.Run`): +```csharp +app.MapRazorComponents(); +``` +### Enable interactive server rendering + +************* +**** WIP **** +************* ### Enable interactive Auto or WebAssembly rendering @@ -61,7 +146,7 @@ No donor needed ... just minimal changes. [!INCLUDE[](~/includes/package-reference.md)] -UPDATE 8.0 'Interactivity type' will change to 'Interactive render mode' at RTM + 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. From bcb42e2ede67e19347c3a36f7650a5a5f3dc92a0 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:38:41 -0400 Subject: [PATCH 3/8] Updates --- aspnetcore/blazor/components/integration.md | 46 +++++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 2a92145a37f8..2cf784600fd3 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -134,11 +134,49 @@ app.MapRazorComponents(); ### Enable interactive server rendering - +Follow the guidance in the [Enable interactive server rendering](#enable-interactive-server-rendering) section. -************* -**** WIP **** -************* +Make the following changes in the app's `Program` file. + +Add a call to `AddInteractiveServerComponents` where Razor component services are added with `AddRazorComponents`: + +```csharp +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); +``` + +Add a call to `AddInteractiveServerRenderMode` where Razor components are mapped with `MapRazorComponents`: + +```csharp +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); +``` + +Add a `Counter` component to the app with the interactive server render mode. + +`Components/Pages/Counter.razor`: + +```razor +@page "/counter" +@attribute [RenderModeInteractiveServer] + +Counter + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} +``` ### Enable interactive Auto or WebAssembly rendering From 42252a2f9f74bb8433a832ed1acaf7d136f55bc9 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:45:28 -0400 Subject: [PATCH 4/8] Updates --- aspnetcore/blazor/components/integration.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 2cf784600fd3..cb5add081709 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -76,8 +76,6 @@ Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's - - From 859489e1851ff09680458773bd6eeb11cb8d2530 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:46:29 -0400 Subject: [PATCH 5/8] Updates --- aspnetcore/blazor/components/integration.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index cb5add081709..00bc9670159a 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -130,6 +130,8 @@ Add `MapRazorComponents` to the app's request processing pipeline with the `App` app.MapRazorComponents(); ``` +When the app is run, the `Welcome` component is accessed at the `/welcome` endpoint. + ### Enable interactive server rendering Follow the guidance in the [Enable interactive server rendering](#enable-interactive-server-rendering) section. @@ -176,6 +178,8 @@ 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. From 5c9dd532fa8d073a5bb316c1c6ebf3c9ff895432 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:14:44 -0400 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Daniel Roth --- aspnetcore/blazor/components/integration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 00bc9670159a..7c906faf7df3 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -49,6 +49,7 @@ Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {APP NAMESPACE} @@ -77,7 +78,6 @@ Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's - @@ -134,7 +134,7 @@ When the app is run, the `Welcome` component is accessed at the `/welcome` endpo ### Enable interactive server rendering -Follow the guidance in the [Enable interactive server rendering](#enable-interactive-server-rendering) section. +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. @@ -158,7 +158,7 @@ Add a `Counter` component to the app with the interactive server render mode. ```razor @page "/counter" -@attribute [RenderModeInteractiveServer] +@rendermode InteractiveServer Counter From cd453f547df3c70c075b6334b4fb944cf0f8f275 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:20:27 -0400 Subject: [PATCH 7/8] Updates --- aspnetcore/blazor/components/integration.md | 197 +------------------- 1 file changed, 8 insertions(+), 189 deletions(-) diff --git a/aspnetcore/blazor/components/integration.md b/aspnetcore/blazor/components/integration.md index 7c906faf7df3..f0b6985f76ec 100644 --- a/aspnetcore/blazor/components/integration.md +++ b/aspnetcore/blazor/components/integration.md @@ -67,6 +67,14 @@ Add the following assets to the app, updating the `{APP NAMESPACE}` to the app's ``` +You can supply a default layout with the parameter of the `RouteView` component: + +```razor + +``` + +For more information, see . + `Components/App.razor`: ```razor @@ -180,196 +188,7 @@ 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 2f363e192d4a6347e3c8b0f1809bb60f03af33d9 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:24:46 -0400 Subject: [PATCH 8/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 f0b6985f76ec..ab1ca2930162 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`.