From 0e3c580ea3aaa12faf4851bfbd7c3ae37f6783cc Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 07:08:25 -0500 Subject: [PATCH 01/13] Blazor prerendering and integration updates --- .../prerendering-and-integration.md | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 0ffa7c1ebd43..2986f30f10f9 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -279,22 +279,18 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and * Add the following `` tag to the `` element in `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC): - ```diff - + + ```html + ``` The `href` value (the *app base path*) in the preceding example assumes that the app resides at the root URL path (`/`). If the app is a sub-application, follow the guidance in the *App base path* section of the article. - * Add a ` - - @await RenderSectionAsync("Scripts", required: false) - + ```html + ``` The framework adds the `blazor.server.js` script to the app. There's no need to manually add a `blazor.server.js` script file to the app. @@ -310,24 +306,21 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and @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} ``` -1. Register the Blazor Server service in `Startup.ConfigureServices`. +1. Register the Blazor Server service in `Program.cs` where services are registered: - `Startup.cs`: - - ```diff - + services.AddServerSideBlazor(); + ```csharp + builder.Services.AddServerSideBlazor(); ``` -1. Add the Blazor Hub endpoint to the endpoints (`app.UseEndpoints`) of `Startup.Configure`. - - `Startup.cs`: +1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped: - ```diff - + endpoints.MapBlazorHub(); + ```csharp + app.MapBlazorHub(); ``` 1. Integrate components into any page or view. For example, add a `Counter` component to the project's `Shared` folder. From cd727b99ed9de1c8505a5949a0ae10b64c6d222e Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 07:48:14 -0500 Subject: [PATCH 02/13] Updates --- .../prerendering-and-integration.md | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 2986f30f10f9..9052902f4d81 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -317,7 +317,9 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and builder.Services.AddServerSideBlazor(); ``` -1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped: +1. Add the Blazor Hub endpoint to the endpoints of `Program.cs` where routes are mapped. + + Place the following line after the call to `MapRazorPages` (Razor Pages) or `MapControllerRoute` (MVC): ```csharp app.MapBlazorHub(); @@ -399,13 +401,13 @@ To support routable Razor components in Razor Pages apps: ```razor @using Microsoft.AspNetCore.Components.Routing - + - + -

Page not found

-

Sorry, but there's nothing here!

+ Not found +

Sorry, there's nothing at this address.

``` @@ -416,16 +418,16 @@ To support routable Razor components in Razor Pages apps: ```cshtml @page "/blazor" + @namespace {APP NAMESPACE}.Pages.Shared + @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = "_Layout"; } - - - + ``` - Components use the shared `_Layout.cshtml` file for their layout. + In this scenario, components use the shared `_Layout.cshtml` file for their layout. configures whether the `App` component: @@ -434,15 +436,10 @@ To support routable Razor components in Razor Pages apps: For more information on the Component Tag Helper, including passing parameters and configuration, see . -1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the `_Host` page as the last endpoint: +1. In the `Program.cs` endpoints, add a low-priority route for the `_Host` page as the last endpoint: - ```diff - app.UseEndpoints(endpoints => - { - endpoints.MapRazorPages(); - endpoints.MapBlazorHub(); - + endpoints.MapFallbackToPage("/_Host"); - }); + ```csharp + app.MapFallbackToPage("/_Host"); ``` 1. Add routable components to the project. From 4c70ba90451d559deaf539babb3f5d44a324ed1f Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 08:00:58 -0500 Subject: [PATCH 03/13] Updates --- .../prerendering-and-integration.md | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 9052902f4d81..f851ef5af6cc 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -484,13 +484,13 @@ To support routable Razor components in MVC apps: ```razor @using Microsoft.AspNetCore.Components.Routing - + - + -

Page not found

-

Sorry, but there's nothing here!

+ Not found +

Sorry, there's nothing at this address.

``` @@ -500,13 +500,13 @@ To support routable Razor components in MVC apps: `Views/Home/_Host.cshtml`: ```cshtml + @namespace {APP NAMESPACE}.Views.Shared + @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = "_Layout"; } - - - + ``` Components use the shared `_Layout.cshtml` file for their layout. @@ -529,20 +529,13 @@ To support routable Razor components in MVC apps: } ``` -1. In the `Startup.Configure` endpoints of `Startup.cs`, add a low-priority route for the controller action that returns the `_Host` view: +1. In the `Program.cs` endpoints, add a low-priority route for the controller action that returns the `_Host` view: - ```diff - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - endpoints.MapBlazorHub(); - + endpoints.MapFallbackToController("Blazor", "Home"); - }); + ```csharp + app.MapFallbackToController("Blazor", "Home"); ``` -1. Add routable components to the project. +1. Create a `Pages` folder in the MVC app and add routable components. `Pages/RoutableCounter.razor`: From aa06bc5aec81185ce50e0e71bac15a4faba06cd4 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 08:42:15 -0500 Subject: [PATCH 04/13] Updates --- .../components/prerendering-and-integration.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index f851ef5af6cc..3e9aeeeacf3c 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -33,7 +33,7 @@ To set up prerendering for a hosted Blazor WebAssembly app: 1. **Delete** the `wwwroot/index.html` file from the Blazor WebAssembly **`Client`** project. -1. In the **`Client`** project, **delete** the following line in `Program.Main` (`Program.cs`): +1. In the **`Client`** project, **delete** the following line in `Program.cs`: ```diff - builder.RootComponents.Add("#app"); @@ -41,12 +41,13 @@ To set up prerendering for a hosted Blazor WebAssembly app: 1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain `_Host.cshtml` and `_Layout.cshtml` files from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder, make the following changes to the `_Layout.cshtml` file: + * Update the `Pages` namespace (for example, `@namespace BlazorHosted.Pages`). * Provide an [`@using`](xref:mvc/views/razor#using) directive for the **`Client`** project (for example, `@using BlazorHosted.Client`). * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`: ```diff - - - + - + + ``` @@ -68,13 +69,11 @@ To set up prerendering for a hosted Blazor WebAssembly app: + ``` -1. In `Startup.Configure` of the **`Server`** project, change the fallback from the `index.html` file to the `_Host.cshtml` page. - - `Startup.cs`: +1. In endpoint mapping of the **`Server`** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page: ```diff - - endpoints.MapFallbackToFile("index.html"); - + endpoints.MapFallbackToPage("/_Host"); + - app.MapFallbackToFile("index.html"); + + app.MapFallbackToPage("/_Host"); ``` 1. Run the **`Server`** project. The hosted Blazor WebAssembly app is prerendered by the **`Server`** project for clients. From 49e41d7b643f1a710c7fd42d248424eeea8b3e9a Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 08:46:58 -0500 Subject: [PATCH 05/13] Updates --- .../blazor/components/prerendering-and-integration.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 3e9aeeeacf3c..f54aa2413904 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -69,6 +69,13 @@ To set up prerendering for a hosted Blazor WebAssembly app: + ``` + * In the `_Host.cshtml` file, change the `{APP NAMESPACE}.Pages` namespace, if it exists, to that of the **`Client`** project. If a namespace of `{APP NAMESPACE}.Pages` doesn't exist, add the namespace for the **`Client`** project: + + ```diff + - @namespace {APP NAMESPACE}.Pages + + @namespace BlazorHosted.Client + ``` + 1. In endpoint mapping of the **`Server`** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page: ```diff From 3bd3bf0211efda93d4e79b53b4ddbeac44c69ccc Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 11:38:22 -0500 Subject: [PATCH 06/13] Updates --- .../blazor/components/prerendering-and-integration.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index f54aa2413904..42c0f2b8e7ab 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -41,15 +41,18 @@ To set up prerendering for a hosted Blazor WebAssembly app: 1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain `_Host.cshtml` and `_Layout.cshtml` files from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder, make the following changes to the `_Layout.cshtml` file: - * Update the `Pages` namespace (for example, `@namespace BlazorHosted.Pages`). + * Update the `Pages` namespace at the top of the file (for example, `@namespace {APP NAMESPACE}.Pages`) to match the namespace of the **`Server`** app's pages (for example, `@namespace BlazorHosted.Server.Pages`). The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. * Provide an [`@using`](xref:mvc/views/razor#using) directive for the **`Client`** project (for example, `@using BlazorHosted.Client`). - * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`: + * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. + * Update the `render-mode` of the Component Tag Helper (`` tag) for the `HeadOutlet` component to `WebAssemblyPrerendered`. ```diff - - + - + + + + ``` > [!NOTE] @@ -69,7 +72,7 @@ To set up prerendering for a hosted Blazor WebAssembly app: + ``` - * In the `_Host.cshtml` file, change the `{APP NAMESPACE}.Pages` namespace, if it exists, to that of the **`Client`** project. If a namespace of `{APP NAMESPACE}.Pages` doesn't exist, add the namespace for the **`Client`** project: + * In the `_Host.cshtml` file, change the `{APP NAMESPACE}.Pages` namespace, if it exists, to that of the **`Client`** project. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Host.cshtml` file. If a namespace for `{APP NAMESPACE}.Pages` doesn't exist, add the namespace for the **`Client`** project (for example, `BlazorHosted.Client`): ```diff - @namespace {APP NAMESPACE}.Pages From d94469d1dff3cb742604a897a6f48b27a2dda241 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 11:51:21 -0500 Subject: [PATCH 07/13] Updates --- .../prerendering-and-integration.md | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 42c0f2b8e7ab..d52f2249ab9b 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -39,12 +39,24 @@ To set up prerendering for a hosted Blazor WebAssembly app: - builder.RootComponents.Add("#app"); ``` -1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain `_Host.cshtml` and `_Layout.cshtml` files from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder, make the following changes to the `_Layout.cshtml` file: +1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain `_Host.cshtml` and `_Layout.cshtml` files from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder: - * Update the `Pages` namespace at the top of the file (for example, `@namespace {APP NAMESPACE}.Pages`) to match the namespace of the **`Server`** app's pages (for example, `@namespace BlazorHosted.Server.Pages`). The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. - * Provide an [`@using`](xref:mvc/views/razor#using) directive for the **`Client`** project (for example, `@using BlazorHosted.Client`). - * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. - * Update the `render-mode` of the Component Tag Helper (`` tag) for the `HeadOutlet` component to `WebAssemblyPrerendered`. + Make the following changes to the `_Layout.cshtml` file: + + * Update the `Pages` namespace at the top of the file to match the namespace of the **`Server`** app's pages. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app's pages that provided the `_Layout.cshtml` file: + + ```diff + - @namespace {APP NAMESPACE}.Pages + + @namespace BlazorHosted.Server.Pages + ``` + + * Add an [`@using`](xref:mvc/views/razor#using) directive for the **`Client`** project at the top of the file: + + ```diff + + @using BlazorHosted.Client + ``` + + * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. Update the `render-mode` of the Component Tag Helper (`` tag) for the `HeadOutlet` component to `WebAssemblyPrerendered`. ```diff - @@ -58,25 +70,27 @@ To set up prerendering for a hosted Blazor WebAssembly app: > [!NOTE] > Leave the `` element that requests the Bootstrap stylesheet (`css/bootstrap/bootstrap.min.css`) in place. - * In the `_Layout.cshtml` file, update the Blazor script source to use the client-side Blazor WebAssembly script: + * Update the Blazor script source to use the client-side Blazor WebAssembly script: ```diff - + ``` - * In the `_Host.cshtml` file, update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with : + In the `_Host.cshtml` file: + + * Change the `Pages` namespace to that of the **`Client`** project. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app's pages that provided the `_Host.cshtml` file: ```diff - - - + + - @namespace {APP NAMESPACE}.Pages + + @namespace BlazorHosted.Client ``` - * In the `_Host.cshtml` file, change the `{APP NAMESPACE}.Pages` namespace, if it exists, to that of the **`Client`** project. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Host.cshtml` file. If a namespace for `{APP NAMESPACE}.Pages` doesn't exist, add the namespace for the **`Client`** project (for example, `BlazorHosted.Client`): + * Update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with : ```diff - - @namespace {APP NAMESPACE}.Pages - + @namespace BlazorHosted.Client + - + + ``` 1. In endpoint mapping of the **`Server`** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page: From d9ddda897e506db6ba541844be6367014eb90aba Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Tue, 21 Sep 2021 12:03:41 -0500 Subject: [PATCH 08/13] Updates --- aspnetcore/blazor/components/prerendering-and-integration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index d52f2249ab9b..d44e781ee06c 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -56,7 +56,7 @@ To set up prerendering for a hosted Blazor WebAssembly app: + @using BlazorHosted.Client ``` - * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. Update the `render-mode` of the Component Tag Helper (`` tag) for the `HeadOutlet` component to `WebAssemblyPrerendered`. + * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. Remove the Component Tag Helper (`` tag) for the `HeadOutlet` component. ```diff - @@ -64,7 +64,6 @@ To set up prerendering for a hosted Blazor WebAssembly app: - + + - + ``` > [!NOTE] From 1f56226315c30b4f4a9853c6d2413b535319230d Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:05:47 -0500 Subject: [PATCH 09/13] Updates --- .../prerendering-and-integration.md | 106 +++++++++++++++--- 1 file changed, 93 insertions(+), 13 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index d44e781ee06c..b668b6a75f34 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -103,9 +103,9 @@ To set up prerendering for a hosted Blazor WebAssembly app: ### Configuration for embedding Razor components into pages and views -The following sections and examples in this article for embedding Razor components of the client Blazor WebAssembly app into pages and views of the server app require additional configuration. +This section covered how to embed Razor components into pages and views of a hosted Blazor WebAssembly app's **`Server`** project. -Use a default Razor Pages or MVC layout file in the **`Server`** project. The **`Server`** project must have the following files and folders. +The **`Server`** project must have the following files and folders. Razor Pages: @@ -119,10 +119,29 @@ MVC: * `Views/_ViewImports.cshtml` * `Views/_ViewStart.cshtml` -Obtain the preceding files from an app created from the Razor Pages or MVC project template. For more information, see or . +The preceding files can be obtained by generating an app from the ASP.NET Core project templates using: + +* Visual Studio's new project creation tools. +* Opening a command shell and executing `dotnet new razor -o {APP NAME}` (Razor Pages) or `dotnet new mvc -o {APP NAME}` (MVC). The option `-o|--output` with a value for the `{APP NAME}` placeholder provides a name for the app and creates a folder for the app. Update the namespaces in the imported `_ViewImports.cshtml` file to match those in use by the **`Server`** project receiving the files. +`Pages/_ViewImports.cshtml` (Razor Pages): + +```razor +@using BlazorHosted.Server +@namespace BlazorHosted.Server.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +``` + +`Views/_ViewImports.cshtml` (MVC): + +```razor +@using BlazorHosted.Server +@using BlazorHosted.Server.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +``` + Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** project's styles. In the following example, the **`Client`** project's namespace is `BlazorHosted.Client`. The `` element can be updated at the same time. `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC): @@ -140,6 +159,16 @@ Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** p </head> ``` +Add the Blazor script tag to the layout file inside where the `Scripts` section is rendered near the closing `</body>` tag: + +```diff + ... + <script src="~/js/site.js" asp-append-version="true"></script> ++ <script src="_framework/blazor.webassembly.js"></script> + @await RenderSectionAsync("Scripts", required: false) +</body> +``` + The imported layout contains `Home` and `Privacy` navigation links. To make the `Home` link point to the hosted Blazor WebAssembly app, change the hyperlink: ```diff @@ -155,7 +184,7 @@ In an MVC layout file: + <a class="nav-link text-dark" href="/">Home</a> ``` -To make the `Privacy` link lead to a privacy page, add a privacy page to the **`Server`** project. +To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy page to the **`Server`** project. `Pages/Privacy.cshtml` in the **`Server`** project: @@ -166,11 +195,13 @@ To make the `Privacy` link lead to a privacy page, add a privacy page to the **` } <h1>Privacy Policy</h1> + +<p>Use this page to detail your site's privacy policy.</p> ``` -If an MVC-based privacy view is preferred, create a privacy view in the **`Server`** project. +For an MVC-based privacy view, create a privacy view in the **`Server`** project. -`View/Home/Privacy.cshtml`: +`View/Home/Privacy.cshtml` in the **`Server` project: ```cshtml @{ @@ -178,9 +209,11 @@ If an MVC-based privacy view is preferred, create a privacy view in the **`Serve } <h1>@ViewData["Title"]</h1> + +<p>Use this page to detail your site's privacy policy.</p> ``` -In the `Home` controller, return the view. +In the `Home` controller of the MVC app, return the view. `Controllers/HomeController.cs`: @@ -191,6 +224,8 @@ In the `Home` controller, return the view. + } ``` +If you import files from a donor app, be sure to update any namespaces in the files to match that of the **`Server`** project (for example, `BlazorHosted.Server`). + Import static assets to the **`Server`** project from the donor project's `wwwroot` folder: * `wwwroot/css` folder and contents @@ -199,12 +234,57 @@ Import static assets to the **`Server`** project from the donor project's `wwwro If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **`Server`** project and remove the `favicon.ico` icon file. -> [!NOTE] -> If the **`Client`** and **`Server`** projects contain the same static asset in their `wwwroot` folders (for example, `favicon.ico`), an exception is thrown because the static asset in each folder shares the same web root path: -> -> > The static web asset '...\favicon.ico' has a conflicting web root path '/wwwroot/favicon.ico' with the project file 'wwwroot\favicon.ico'. -> -> Therefore, host a static asset in either `wwwroot` folder, not both. +Avoid placing the same file (for example, `favicon.ico`) into both the **`Client`** and **`Server`** `wwwroot` folders. If the same file is present in both folders an exception is thrown because the static asset in each folder shares the same web root path: + +> The static web asset '...\favicon.ico' has a conflicting web root path '/wwwroot/favicon.ico' with the project file 'wwwroot\favicon.ico'. + +Therefore, host a static asset in either `wwwroot` folder, not both. + +After adopting the preceding configuration, embed Razor components into pages or views of the **`Server`** project. The following example embeds the Blazor WebAssembly app's `Counter` component into the privacy page or view shown earlier in this section. + +`Pages/Privacy.cshtml` in the **`Server`** project: + +```cshtml +@page +@model BlazorHosted.Server.Pages.PrivacyModel +@using BlazorHosted.Client.Pages +@{ +} + +<h1>Privacy Policy</h1> + +<p>Use this page to detail your site's privacy policy.</p> + +<h2>Counter component from the Client project</h2> + +<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" /> +``` + +For an MVC-based privacy view, create a privacy view in the **`Server`** project. + +`View/Home/Privacy.cshtml` in the **`Server` project: + +```cshtml +@using BlazorHosted.Client.Pages +@{ + ViewData["Title"] = "Privacy Policy"; +} + +<h1>@ViewData["Title"]</h1> + +<p>Use this page to detail your site's privacy policy.</p> + +<h2>Counter component from the Client project</h2> + +<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" /> +``` + +The preceding examples specify an `@using` statement (`@using BlazorHosted.Client.Pages`) for the **`Client`** project's Razor components in its `Pages` folder. Alternatively, the page or view can use a fully-qualified reference to the component in the Component Tag Helper. With the fully-qualified type, the `@using` statement isn't required: + +```razor +<component type="typeof(BlazorHosted.Client.Pages.Counter)" + render-mode="WebAssemblyPrerendered" /> +``` ## Render components in a page or view with the Component Tag Helper From b7e5258dcf18b895896efdec38e6cf5d97a256ca Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:06:36 -0500 Subject: [PATCH 10/13] Updates --- aspnetcore/blazor/components/prerendering-and-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index b668b6a75f34..24da2ff2cabc 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -201,7 +201,7 @@ To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy p For an MVC-based privacy view, create a privacy view in the **`Server`** project. -`View/Home/Privacy.cshtml` in the **`Server` project: +`View/Home/Privacy.cshtml` in the **`Server`** project: ```cshtml @{ From ba70b9d39ca9418d49cfe0920aa587f39fcf193e Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:17:18 -0500 Subject: [PATCH 11/13] Updates --- .../prerendering-and-integration.md | 59 ++----------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 24da2ff2cabc..6f17d7de7c66 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -103,7 +103,7 @@ To set up prerendering for a hosted Blazor WebAssembly app: ### Configuration for embedding Razor components into pages and views -This section covered how to embed Razor components into pages and views of a hosted Blazor WebAssembly app's **`Server`** project. +The following sections and examples embedding Razor components from the **`Client`** Blazor WebAssembly app into pages and views of the server app require additional configuration. The **`Server`** project must have the following files and folders. @@ -159,16 +159,6 @@ Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** p </head> ``` -Add the Blazor script tag to the layout file inside where the `Scripts` section is rendered near the closing `</body>` tag: - -```diff - ... - <script src="~/js/site.js" asp-append-version="true"></script> -+ <script src="_framework/blazor.webassembly.js"></script> - @await RenderSectionAsync("Scripts", required: false) -</body> -``` - The imported layout contains `Home` and `Privacy` navigation links. To make the `Home` link point to the hosted Blazor WebAssembly app, change the hyperlink: ```diff @@ -240,51 +230,10 @@ Avoid placing the same file (for example, `favicon.ico`) into both the **`Client Therefore, host a static asset in either `wwwroot` folder, not both. -After adopting the preceding configuration, embed Razor components into pages or views of the **`Server`** project. The following example embeds the Blazor WebAssembly app's `Counter` component into the privacy page or view shown earlier in this section. - -`Pages/Privacy.cshtml` in the **`Server`** project: - -```cshtml -@page -@model BlazorHosted.Server.Pages.PrivacyModel -@using BlazorHosted.Client.Pages -@{ -} - -<h1>Privacy Policy</h1> +After adopting the preceding configuration, embed Razor components into pages or views of the **`Server`** project. Use the guidance in the following sections of this article: -<p>Use this page to detail your site's privacy policy.</p> - -<h2>Counter component from the Client project</h2> - -<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" /> -``` - -For an MVC-based privacy view, create a privacy view in the **`Server`** project. - -`View/Home/Privacy.cshtml` in the **`Server` project: - -```cshtml -@using BlazorHosted.Client.Pages -@{ - ViewData["Title"] = "Privacy Policy"; -} - -<h1>@ViewData["Title"]</h1> - -<p>Use this page to detail your site's privacy policy.</p> - -<h2>Counter component from the Client project</h2> - -<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" /> -``` - -The preceding examples specify an `@using` statement (`@using BlazorHosted.Client.Pages`) for the **`Client`** project's Razor components in its `Pages` folder. Alternatively, the page or view can use a fully-qualified reference to the component in the Component Tag Helper. With the fully-qualified type, the `@using` statement isn't required: - -```razor -<component type="typeof(BlazorHosted.Client.Pages.Counter)" - render-mode="WebAssemblyPrerendered" /> -``` +* *Render components in a page or view with the Component Tag Helper* +* *Render components in a page or view with a CSS selector* ## Render components in a page or view with the Component Tag Helper From 93c54b96b2ad0b723f3456b7a4abae8b78c9c22a Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Wed, 22 Sep 2021 10:36:09 -0500 Subject: [PATCH 12/13] Updates --- .../prerendering-and-integration.md | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index 6f17d7de7c66..bf3231200399 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -270,18 +270,18 @@ Additional work might be required depending on the static resources that compone ## Render components in a page or view with a CSS selector -After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **`Client`** project of a hosted Blazor WebAssembly solution in `Program.Main`. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **`Client`** project's namespace is `BlazorHosted.Client`. +After [configuring the solution](#solution-configuration), including the [additional configuration](#configuration-for-embedding-razor-components-into-pages-and-views), add root components to the **`Client`** project of a hosted Blazor WebAssembly solution in the `Program.cs` file. In the following example, the `Counter` component is declared as a root component with a CSS selector that selects the element with the `id` that matches `counter-component`. In the following example, the **`Client`** project's namespace is `BlazorHosted.Client`. -In `Program.cs` of the **`Client`** project, add the namespace for the project's Razor components to the top of the file: +In `Program.cs` file of the **`Client`** project, add the namespace for the project's Razor components to the top of the file: -```diff -+ using BlazorHosted.Client.Pages; +```csharp +using BlazorHosted.Client.Pages; ``` -After the `builder` is established in `Program.Main`, add the `Counter` component as a root component: +After the `builder` is established in `Program.cs`, add the `Counter` component as a root component: -```diff -+ builder.RootComponents.Add<Counter>("#counter-component"); +```csharp +builder.RootComponents.Add<Counter>("#counter-component"); ``` In the following Razor Pages example, the `Counter` component is rendered in a page. To make the component interactive, the Blazor WebAssembly script is included in the page's [render section](xref:mvc/views/layout#sections). @@ -303,11 +303,18 @@ Run the **`Server`** project. Navigate to the Razor page at `/razorpagescounter2 Additional work might be required depending on the static resources that components use and how layout pages are organized in an app. Typically, scripts are added to a page or view's `Scripts` render section and stylesheets are added to the layout's `<head>` element content. > [!NOTE] -> The preceding example throws a <xref:Microsoft.JSInterop.JSException> if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with a CSS selector. Navigating to one of the **`Client`** project's Razor components throws the following exception: -> -> > Microsoft.JSInterop.JSException: Could not find any element matching selector '#counter-component'. +> The preceding example throws a <xref:Microsoft.JSInterop.JSException> if a Blazor WebAssembly app is prerendered and integrated into a Razor Pages or MVC app **simultaneously** with the use of a CSS selector. Navigating to one of the **`Client`** project's Razor components or navigating to a page or view of the **`Server`** with an embedded component throws one or more <xref:Microsoft.JSInterop.JSException>. > > This is normal behavior because prerendering and integrating a Blazor WebAssembly app with routable Razor components is incompatible with the use of CSS selectors. +> +> If you've been working with the examples in the preceding sections and just wish to see the CSS selector work in your sample app, comment out the specification of the `App` root component of the **`Client`** project's `Program.cs` file: +> +> ```diff +> - builder.RootComponents.Add<App>("#app"); +> + //builder.RootComponents.Add<App>("#app"); +> ``` +> +> Navigate to the page or view with the embedded Razor component that uses a CSS selector (for example, `/razorpagescounter2` of the preceding example). The page or view loads with the embedded component, and the embedded component functions as expected. ::: zone-end From 07e3f3f6f8a1188ef3c8c57e6a6ba5e639871540 Mon Sep 17 00:00:00 2001 From: guardrex <1622880+guardrex@users.noreply.github.com> Date: Thu, 23 Sep 2021 06:44:46 -0500 Subject: [PATCH 13/13] Updates --- .../prerendering-and-integration.md | 116 ++++++++++++------ 1 file changed, 76 insertions(+), 40 deletions(-) diff --git a/aspnetcore/blazor/components/prerendering-and-integration.md b/aspnetcore/blazor/components/prerendering-and-integration.md index bf3231200399..0473df54d90d 100644 --- a/aspnetcore/blazor/components/prerendering-and-integration.md +++ b/aspnetcore/blazor/components/prerendering-and-integration.md @@ -39,31 +39,45 @@ To set up prerendering for a hosted Blazor WebAssembly app: - builder.RootComponents.Add<App>("#app"); ``` -1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain `_Host.cshtml` and `_Layout.cshtml` files from a project created from the Blazor Server template with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder: +1. Add `_Host.cshtml` and `_Layout.cshtml` files to the **`Server`** project's `Pages` folder. You can obtain the files from a project created from the Blazor Server template using Visual Studio or using the .NET CLI with the `dotnet new blazorserver -o BlazorServer` command in a command shell (the `-o BlazorServer` option creates a folder for the project). After placing the files into the **`Server`** project's `Pages` folder: Make the following changes to the `_Layout.cshtml` file: - * Update the `Pages` namespace at the top of the file to match the namespace of the **`Server`** app's pages. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app's pages that provided the `_Layout.cshtml` file: + * Update the `Pages` namespace at the top of the file to match the namespace of the **`Server`** app's pages. The `{APP NAMESPACE}` placeholder in the following example represents the namespace of the donor app's pages that provided the `_Layout.cshtml` file: + + Delete: ```diff - @namespace {APP NAMESPACE}.Pages - + @namespace BlazorHosted.Server.Pages + ``` + + Add: + + ```razor + @namespace BlazorHosted.Server.Pages ``` * Add an [`@using`](xref:mvc/views/razor#using) directive for the **`Client`** project at the top of the file: - ```diff - + @using BlazorHosted.Client + ```razor + @using BlazorHosted.Client ``` * Update the stylesheet links to point to the WebAssembly project's stylesheets. In the following example, the client project's namespace is `BlazorHosted.Client`. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app that provided the `_Layout.cshtml` file. Remove the Component Tag Helper (`<component>` tag) for the `HeadOutlet` component. + Delete: + ```diff - <link href="css/site.css" rel="stylesheet" /> - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" /> - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> - + <link href="css/app.css" rel="stylesheet" /> - + <link href="BlazorHosted.Client.styles.css" rel="stylesheet" /> + ``` + + Add: + + ```razor + <link href="css/app.css" rel="stylesheet" /> + <link href="BlazorHosted.Client.styles.css" rel="stylesheet" /> ``` > [!NOTE] @@ -71,39 +85,67 @@ To set up prerendering for a hosted Blazor WebAssembly app: * Update the Blazor script source to use the client-side Blazor WebAssembly script: + Delete: + ```diff - <script src="_framework/blazor.server.js"></script> - + <script src="_framework/blazor.webassembly.js"></script> + ``` + + Add: + + ```html + <script src="_framework/blazor.webassembly.js"></script> ``` In the `_Host.cshtml` file: * Change the `Pages` namespace to that of the **`Client`** project. The `{APP NAMESPACE}` placeholder represents the namespace of the donor app's pages that provided the `_Host.cshtml` file: + Delete: + ```diff - @namespace {APP NAMESPACE}.Pages - + @namespace BlazorHosted.Client + ``` + + Add: + + ```razor + @namespace BlazorHosted.Client ``` * Update the `render-mode` of the [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) to prerender the root `App` component with <xref:Microsoft.AspNetCore.Mvc.Rendering.RenderMode.WebAssemblyPrerendered>: + Delete: + ```diff - <component type="typeof(App)" render-mode="ServerPrerendered" /> - + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" /> + ``` + + Add: + + ```razor + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" /> ``` 1. In endpoint mapping of the **`Server`** project in `Program.cs`, change the fallback from the `index.html` file to the `_Host.cshtml` page: + Delete: + ```diff - app.MapFallbackToFile("index.html"); - + app.MapFallbackToPage("/_Host"); + ``` + + Add: + + ```csharp + app.MapFallbackToPage("/_Host"); ``` 1. Run the **`Server`** project. The hosted Blazor WebAssembly app is prerendered by the **`Server`** project for clients. ### Configuration for embedding Razor components into pages and views -The following sections and examples embedding Razor components from the **`Client`** Blazor WebAssembly app into pages and views of the server app require additional configuration. +The following sections and examples for embedding Razor components from the **`Client`** Blazor WebAssembly app into pages and views of the server app require additional configuration. The **`Server`** project must have the following files and folders. @@ -142,7 +184,7 @@ Update the namespaces in the imported `_ViewImports.cshtml` file to match those @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers ``` -Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** project's styles. In the following example, the **`Client`** project's namespace is `BlazorHosted.Client`. The `<title>` element can be updated at the same time. +Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** project's styles. In the following example, the **`Client`** project's namespace is `BlazorHosted.Client`. The `<title>` element can be updated at the same time. The `{APP NAME}` placeholder represents the donor project's app name. `Pages/Shared/_Layout.cshtml` (Razor Pages) or `Views/Shared/_Layout.cshtml` (MVC): @@ -150,7 +192,7 @@ Update the imported layout file (`_Layout.cshtml`) to include the **`Client`** p <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> -- <title>@ViewData["Title"] - DonorProject +- @ViewData["Title"] - {APP NAME} + @ViewData["Title"] - BlazorHosted @@ -180,11 +222,11 @@ To make the `Privacy` link lead to a privacy page (Razor Pages), add a privacy p ```cshtml @page -@model BlazorHosted.Server.Pages.PrivacyModel +@model PrivacyModel @{ + ViewData["Title"] = "Privacy Policy"; } - -

Privacy Policy

+

@ViewData["Title"]

Use this page to detail your site's privacy policy.

``` @@ -197,7 +239,6 @@ For an MVC-based privacy view, create a privacy view in the **`Server`** project @{ ViewData["Title"] = "Privacy Policy"; } -

@ViewData["Title"]

Use this page to detail your site's privacy policy.

@@ -205,13 +246,13 @@ For an MVC-based privacy view, create a privacy view in the **`Server`** project In the `Home` controller of the MVC app, return the view. -`Controllers/HomeController.cs`: +Add the following code to `Controllers/HomeController.cs`: -```diff -+ public IActionResult Privacy() -+ { -+ return View(); -+ } +```csharp +public IActionResult Privacy() +{ + return View(); +} ``` If you import files from a donor app, be sure to update any namespaces in the files to match that of the **`Server`** project (for example, `BlazorHosted.Server`). @@ -224,11 +265,12 @@ Import static assets to the **`Server`** project from the donor project's `wwwro If the donor project is created from an ASP.NET Core project template and the files aren't modified, you can copy the entire `wwwroot` folder from the donor project into the **`Server`** project and remove the `favicon.ico` icon file. -Avoid placing the same file (for example, `favicon.ico`) into both the **`Client`** and **`Server`** `wwwroot` folders. If the same file is present in both folders an exception is thrown because the static asset in each folder shares the same web root path: - -> The static web asset '...\favicon.ico' has a conflicting web root path '/wwwroot/favicon.ico' with the project file 'wwwroot\favicon.ico'. - -Therefore, host a static asset in either `wwwroot` folder, not both. +> [!WARNING] +> Avoid placing the same file (for example, `favicon.ico`) into both the **`Client`** and **`Server`** `wwwroot` folders. If the same file is present in both folders an exception is thrown because the static asset in each folder shares the same web root path: +> +> > The static web asset '...\favicon.ico' has a conflicting web root path '/wwwroot/favicon.ico' with the project file 'wwwroot\favicon.ico'. +> +> Therefore, host a static asset in either `wwwroot` folder, not both. After adopting the preceding configuration, embed Razor components into pages or views of the **`Server`** project. Use the guidance in the following sections of this article: @@ -369,7 +411,7 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and @using {APP NAMESPACE} ``` -1. Register the Blazor Server service in `Program.cs` where services are registered: +1. Register the Blazor Server services in `Program.cs` where services are registered: ```csharp builder.Services.AddServerSideBlazor(); @@ -418,13 +460,9 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and ViewData["Title"] = "Home page"; } -
- -
+ ``` - In the preceding example, replace the `{APP NAMESPACE}` placeholder with the app's namespace. - **MVC**: In the project's `Index` view of an MVC app, add the `Counter` component's namespace and embed the component into the view. When the `Index` view loads, the `Counter` component is prerendered in the page. In the following example, replace the `{APP NAMESPACE}` placeholder with the project's namespace. @@ -437,9 +475,7 @@ An existing Razor Pages or MVC app can integrate Razor components into pages and ViewData["Title"] = "Home Page"; } -
- -
+ ``` For more information, see the [Render components from a page or view](#render-components-from-a-page-or-view) section. @@ -500,7 +536,7 @@ To support routable Razor components in Razor Pages apps: app.MapFallbackToPage("/_Host"); ``` -1. Add routable components to the project. +1. Add routable components to the project. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates. `Pages/RoutableCounter.razor`: @@ -593,7 +629,7 @@ To support routable Razor components in MVC apps: app.MapFallbackToController("Blazor", "Home"); ``` -1. Create a `Pages` folder in the MVC app and add routable components. +1. Create a `Pages` folder in the MVC app and add routable components. The following example is a `RoutableCounter` component based on the `Counter` component in the Blazor project templates. `Pages/RoutableCounter.razor`: