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

Blazor migration guidance 8.0 #30671

Merged
merged 20 commits into from
Oct 20, 2023
206 changes: 166 additions & 40 deletions aspnetcore/migration/70-80.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,64 +73,190 @@ In the project file, update each [Microsoft.AspNetCore.*](https://www.nuget.org/

## Blazor

We hope to have the Blazor section of this article updated soon.<!--In the meantime, see the following resources: -->
The following migration scenarios are covered:

### Adopt .NET 8 features
* [Update a Blazor Server app](#update-a-blazor-server-app)
guardrex marked this conversation as resolved.
Show resolved Hide resolved
* [Add Auto component rendering to a Blazor Server app](#add-auto-component-rendering-to-a-blazor-server-app)
* [Upgrade a hosted Blazor WebAssembly app](#upgrade-a-hosted-blazor-webassembly-app)

After following the guidance earlier in this article to update an app to 8.0, adopt specific features by following the links in <xref:aspnetcore-8#blazor>.
For scenarios not covered or to upgrade to a Blazor Web App, we recommend:

<!-- UPDATE 8.0
* Creating a new app from the Blazor Web App project template. For more information, see <xref:blazor/tooling>.
* Move the your app's components and code to the new Blazor Web App app, making modifications to adopt 8.0 features as desired. For more information, see <xref:aspnetcore-8#blazor>.

To adopt all of the [new 8.0 features for Blazor apps](xref:aspnetcore-7#blazor), we recommend the following process:
### Update a Blazor Server app
guardrex marked this conversation as resolved.
Show resolved Hide resolved

* Create a new 8.0 Blazor project from one of the Blazor project templates. For more information, see <xref:blazor/tooling>.
* Move the app's components and code to the 8.0 app making modifications to adopt the new 8.0 features. -->
Blazor Server apps are supported in .NET 8. Make the following changes to update the app's code, which permits adopting new .NET 8 features:

<!-- HOLD: See https://github.com/dotnet/AspNetCore.Docs/issues/27848
1. Update the project file to target `net8.0` and package references to the latest .NET 8 versions:

### Simplify component parameter binding
```diff
- <TargetFramework>net7.0</TargetFramework>
+ <TargetFramework>net8.0</TargetFramework>
```

In prior Blazor releases, binding across multiple components required binding to properties with `get`/`set` accessors.
1. Move the contents of the `App` component (`App.razor`) to a new `Routes` component file (`Routes.razor`) added to the app. Leave the empty `App.razor` file in the app.

In .NET 6 and earlier:
1. Add an entry to the `_Imports.razor` file to make shorthand render modes available to the app:

```razor
<NestedGrandchild @bind-GrandchildMessage="BoundValue" />
```razor
@using static Microsoft.AspNetCore.Components.Web.RenderMode
```

@code {
...
1. Move the content in the `_Host` page (`Pages/_Host.cshtml`) to the empty `App.razor` file and delete the `Pages/_Host.cshtml` file. Proceed to make the following changes to the `App` component.

private string BoundValue
{
get => ChildMessage ?? string.Empty;
set => ChildMessageChanged.InvokeAsync(value);
}
}
```
> [!NOTE]
> In the following example, the app's namespace is `Net8BlazorServer`.

In .NET 7, you can use the new `@bind:get` and `@bind:set` modifiers to support two-way data binding and simplify the binding syntax:
Remove the following lines at the top of the file:

```razor
<NestedGrandchild @bind-GrandchildMessage:get="ChildMessage"
@bind-GrandchildMessage:set="ChildMessageChanged" />
```
```diff
- @page "/"
- @using Microsoft.AspNetCore.Components.Web
- @namespace Net8BlazorServer.Pages
- @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
```

Replace them with the following:

```razor
@inject IHostEnvironment Env
```

Remove the tilde (~) from the value of `href` for the `<base>` tag:

```diff
- <base href="~/" />
+ <base href="/" />
```

Remove the Component Tag Helper for the `HeadOutlet` component:

```diff
- <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
```

Replace it with the following:

```razor
<HeadOutlet @rendermode="RenderMode.InteractiveServer" />
guardrex marked this conversation as resolved.
Show resolved Hide resolved
```

Remove the Component Tag Helper for the `App` component:

```diff
- <component type="typeof(App)" render-mode="ServerPrerendered" />
```

Replace it with the following:

```razor
<Routes @rendermode="RenderMode.InteractiveServer" />
guardrex marked this conversation as resolved.
Show resolved Hide resolved
```

Remove the Environment Tag Helpers for error UI:

```diff
- <environment include="Staging,Production">
- An error has occurred. This application may no longer respond until reloaded.
- </environment>
- <environment include="Development">
- An unhandled exception has occurred. See browser dev tools for details.
- </environment>
```

Replace them with the following:

```razor
@if (Env.IsDevelopment())
{
<text>An unhandled exception has occurred. See browser dev tools for details.</text>
}
else
{
<text>An error has occurred. This application may no longer respond until reloaded.</text>
}
```

Change the Blazor script from `blazor.server.js` to `blazor.web.js`:

```diff
- <script src="_framework/blazor.server.js"></script>
+ <script src="_framework/blazor.web.js"></script>
```

> [!IMPORTANT]
> The `@bind:get` and `@bind:set` features are receiving further updates at this time. To take advantage of the latest updates, confirm that you've installed the [latest SDK](https://dotnet.microsoft.com/download/dotnet/7.0).
>
> Using an event callback parameter (`[Parameter] public EventCallback<string> ValueChanged { get; set; }`) isn't supported. Instead, pass an <xref:System.Action>-returning or <xref:System.Threading.Tasks.Task>-returning method to `@bind:set`.
>
> For more information, see the following resources:
>
> * [Blazor `@bind:after` not working on .NET 7 RTM release (dotnet/aspnetcore #44957)](https://github.com/dotnet/aspnetcore/issues/44957)
> * [`BindGetSetAfter701` sample app (javiercn/BindGetSetAfter701 GitHub repository)](https://github.com/javiercn/BindGetSetAfter701)
1. Update `Program.cs`:

For more information, see the following content in the *Data binding* article:
> [!NOTE]
> In the following example, the app's namespace is `Net8BlazorServer`.

* [Introduction](xref:blazor/components/data-binding?view=aspnetcore-7.0)
* [Bind across more than two components](xref:blazor/components/data-binding?view=aspnetcore-7.0#bind-across-more-than-two-components)
Add a `using` statement for the app's namespace:

-->
```csharp
using Net8BlazorServer;
```

Replace `AddServerSideBlazor` with `AddRazorComponents` and a chained call to `AddInteractiveServerComponents`.

Remove the following line:

```diff
- builder.Services.AddServerSideBlazor();
```

Replace it with the following:

```csharp
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
```

Replace `MapBlazorHub` with `MapRazorComponents`, supplying the `App` component as the root component type, and a chained call to `AddInteractiveServerRenderMode`.

Remove the following line:

```diff
- app.MapBlazorHub();
```

Replace it with the following:

```csharp
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
```

Remove the endpoint mapping that falls back to the `_Host` page:

```diff
- app.MapFallbackToPage("/_Host");
```

1. If the Blazor Server app wasn't prerendering content, you can continue to disable prerendering for the updated app. In the `App` component, change the value assigned to the `@rendermode` Razor directive attributes for the `HeadOutlet` and `Routes` components:

```diff
- @rendermode="RenderMode.InteractiveServer"
guardrex marked this conversation as resolved.
Show resolved Hide resolved
+ @rendermode="new InteractiveServerRenderMode(prerender: false)"
```

For more information, see <xref:blazor/components/render-modes?view=aspnetcore-8.0&preserve-view=true#prerendering>.

### Add Auto component rendering to a Blazor Server app



### Upgrade a hosted Blazor WebAssembly app



### Adopt .NET 8 features
guardrex marked this conversation as resolved.
Show resolved Hide resolved

After following the guidance earlier in this article to update an app to 8.0, adopt specific features by following the links in <xref:aspnetcore-8#blazor>.

To adopt all of the [new 8.0 features for Blazor apps](xref:aspnetcore-8#blazor) at one time, we recommend the following process:

* Create a new 8.0 Blazor project from one of the Blazor project templates. For more information, see <xref:blazor/tooling>.
* Move the app's components and code to the new 8.0 app, making modifications to adopt 8.0 features as desired.

## Update Docker images

Expand Down