Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Blazor support to an ASP.NET Core app #30791

Merged
merged 8 commits into from
Oct 20, 2023
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 152 additions & 7 deletions aspnetcore/blazor/components/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,171 @@ 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). -->
* 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.

<!-- HOLD

## Add Blazor support to an ASP.NET Core app

This section covers adding Blazor support to an ASP.NET Core app.
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`.

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

`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
guardrex marked this conversation as resolved.
Show resolved Hide resolved
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components
```

`Components/Routes.razor`:

```razor
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" />
guardrex marked this conversation as resolved.
Show resolved Hide resolved
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
```

`Components/App.razor`:

```razor
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="{APP NAMESPACE}.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
guardrex marked this conversation as resolved.
Show resolved Hide resolved
<HeadOutlet />
</head>

<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>

</html>
```

`Components/Pages/Welcome.razor`:

```razor
@page "/welcome"

<PageTitle>Welcome!</PageTitle>

<h1>Welcome to Blazor!</h1>

<p>@message</p>

@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();
```

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<App>();
```

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.
guardrex marked this conversation as resolved.
Show resolved Hide resolved

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<App>()
.AddInteractiveServerRenderMode();
```

Add a `Counter` component to the app with the interactive server render mode.

`Components/Pages/Counter.razor`:

```razor
@page "/counter"
@attribute [RenderModeInteractiveServer]
guardrex marked this conversation as resolved.
Show resolved Hide resolved

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()
{
currentCount++;
}
}
```

When the app is run, the `Counter` component is accessed at the `/counter` endpoint.

### Enable interactive Auto or WebAssembly rendering
Copy link
Member

@danroth27 danroth27 Oct 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also like to simplify this section to make it more minimalistic:

  • Clarify at the beginning that the user should first enable support for static server rendering if they don't have that already, like we do in the section on enabling interactive server rendering.
  • When creating the donor project use the --empty option. We're just trying to enable the project structure, not include the sample pages and content.
  • Remove step 2 to copy over Bootstrap and the styles. The existing app might not be using Bootstrap.
  • Remove step 4. The generated project without sample pages won't have a Components folder. We'll need to add a step to add a component to the client project to demonstrate that it's working.
  • Simplify step 10 given that the user has done a bunch of the described changes already as part of enabling static server rendering. Key things are to enable interactive WebAssembly support and to add the client project as an additional assembly
  • Step 11 is huge! 😮 I'd like to shrink it way down to just adding another Pages/Counter2.razor component to the client project with @rendermode InteractiveWebAssembly or InteractiveAuto.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ... I'll put it on the new PR tho. That way, all lines go in clean for feedback.


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

UPDATE 8.0 'Interactivity type' will change to 'Interactive render mode' at RTM
<!-- 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 <xref:blazor/tooling> article, selecting support for the following template features when generating the Blazor Web App.

Expand Down Expand Up @@ -224,8 +371,6 @@ UPDATE 8.0 'Interactivity type' will change to 'Interactive render mode' at RTM

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

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