Skip to content
Merged
Changes from all 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
106 changes: 66 additions & 40 deletions aspnetcore/migration/50-to-60.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ author: rick-anderson
description: Learn how to migrate an ASP.NET Core 5.0 project to ASP.NET Core 6.0.
ms.author: riande
monikerRange: '>= aspnetcore-5.0'
ms.date: 10/15/2021
ms.date: 10/25/2021
no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
uid: migration/50-to-60
---
Expand All @@ -30,7 +30,7 @@ This article explains how to update an existing ASP.NET Core 5.0 project to ASP.

## Update .NET SDK version in global.json

If you rely upon a [global.json](/dotnet/core/tools/global-json) file to target a specific .NET SDK version, update the `version` property to the .NET 6.0 SDK version that's installed. For example:
If you rely upon a [`global.json`](/dotnet/core/tools/global-json) file to target a specific .NET SDK version, update the `version` property to the .NET 6.0 SDK version that's installed. For example:

```diff
{
Expand Down Expand Up @@ -60,7 +60,7 @@ Update the project file's [Target Framework Moniker (TFM)](/dotnet/standard/fram

## Update package references

In the project file, update each [Microsoft.AspNetCore.*](https://www.nuget.org/packages?q=Microsoft.AspNetCore.*) and [Microsoft.Extensions.*](https://www.nuget.org/packages?q=Microsoft.Extensions.*) package reference's `Version` attribute to 6.0.0 or later. For example:
In the project file, update each [`Microsoft.AspNetCore.*`](https://www.nuget.org/packages?q=Microsoft.AspNetCore.*) and [`Microsoft.Extensions.*`](https://www.nuget.org/packages?q=Microsoft.Extensions.*) package reference's `Version` attribute to 6.0.0 or later. For example:

```diff
<ItemGroup>
Expand All @@ -81,12 +81,12 @@ The new .NET 6 minimal hosting model for ASP.NET Core apps requires only one fil

The minimal hosting model:

* Significantly reduces the number of files and lines of code required to create an app. Only one file is needed with 4 lines of code.
* Unifies *Startup.cs* and *Program.cs* into a single *Program.cs* file.
* Uses [Top-level statements](/dotnet/csharp/fundamentals/program-structure/top-level-statements) to minimize the code required for an app.
* Uses [Global using directives](/dotnet/csharp/whats-new/csharp-10#global-using-directives) to eliminate or minimize the number of [`using statement`](/dotnet/csharp/language-reference/keywords/using-statement) lines required.
* Significantly reduces the number of files and lines of code required to create an app. Only one file is needed with four lines of code.
* Unifies `Startup.cs` and `Program.cs` into a single `Program.cs` file.
* Uses [top-level statements](/dotnet/csharp/fundamentals/program-structure/top-level-statements) to minimize the code required for an app.
* Uses [global `using` directives](/dotnet/csharp/whats-new/csharp-10#global-using-directives) to eliminate or minimize the number of [`using` statement](/dotnet/csharp/language-reference/keywords/using-statement) lines required.

The following code displays the *Startup.cs* and *Program.cs* files from an ASP.NET Core 5 Web App template (Razor Pages) with unused `using` statements removed:
The following code displays the `Startup.cs` and `Program.cs` files from an ASP.NET Core 5 Web App template (Razor Pages) with unused `using` statements removed:

[!code-csharp[](50-to-60/samples/WebAppRPv5/Startup.cs)]
[!code-csharp[](50-to-60/samples/WebAppRPv5/Program.cs)]
Expand All @@ -97,40 +97,39 @@ In ASP.NET Core 6, the preceding code is replaced by the following:

The preceding ASP.NET Core 6 sample shows how:

* <xref:Microsoft.AspNetCore.Hosting.StartupBase.ConfigureServices*> is replaced with [WebApplication.Services](xref:Microsoft.AspNetCore.Builder.WebApplication.Services).
* <xref:Microsoft.AspNetCore.Hosting.StartupBase.ConfigureServices*> is replaced with [`WebApplication.Services`](xref:Microsoft.AspNetCore.Builder.WebApplication.Services).
* `builder.Build()` returns a configured <xref:Microsoft.AspNetCore.Builder.WebApplication> to the variable `app`. <xref:Microsoft.AspNetCore.Hosting.StartupBase.Configure*> is replaced with configuration calls to to same services using `app`.

Detailed examples of migrating ASP.NET Core 5 `Startup` code to ASP.NET Core 6 using the minimal hosting model are provided later in this document.

There are a few changes to the other files generated for the Web App template:

* *Index.cshtml* and *Privacy.cshtml* have the unused `using` statements removed.
* `RequestId` in *Error.cshtml* is declared as a [nullable reference type](/dotnet/csharp/language-reference/builtin-types/nullable-reference-types):
* `Index.cshtml` and `Privacy.cshtml` have the unused `using` statements removed.
* `RequestId` in `Error.cshtml` is declared as a [nullable reference type (NRT)](/dotnet/csharp/language-reference/builtin-types/nullable-reference-types):

```diff
- public string RequestId { get; set; }
+ public string? RequestId { get; set; }
```

* `"Microsoft.Hosting.Lifetime": "Information"` was removed from both *appsettings.json* and *appsettings.Development.json*:
* `"Microsoft.Hosting.Lifetime": "Information"` was removed from both `appsettings.json` and `appsettings.Development.json`:

```diff
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

```

See [Frequently asked questions](#faq) in this document for more details on the new hosting model.
For more details on the new hosting model, see the [Frequently asked questions](#faq) section. For more information on the adoption of NRTs and .NET compiler null-state analysis, see the [Nullable reference types (NRTs) and .NET compiler null-state static analysis](#nullable-reference-types-nrts-and-net-compiler-null-state-static-analysis) section.

### Differences between the ASP.NET Core 5 and 6 hosting models

* In [development mode](xref:fundamentals/environments), the developer exception page middleware is enabled by default.
* The app name defaults to the entry point assembly's name: `Assembly.GetEntryAssembly().GetName().FullName`. When using the <xref:Microsoft.AspNetCore.Builder.WebApplicationBuilder> in a library, explicitly change the app name to the library's assembly to allow MVC's [application part discovery](xref:mvc/extensibility/app-parts) to work. See [Change the content root, app name, and environment](xref:migration/50-to-60-samples#ccr) in this document for detailed instructions.
* The endpoint routing middleware wraps the entire middleware pipeline, therefore there's no need to have explicit calls to `UseEndpoints` to register routes. `UseRouting` can still be used to specify where route matching happens but `UseRouting` doesn't need to be explicitly called.
* The [pipeline](xref:fundamentals/middleware/index) is created before any <xref:Microsoft.AspNetCore.Hosting.IStartupFilter> runs, therefore exceptions caused while building the pipeline aren't visible to the `IStartupFilter` call chain.
* Some tools, such as EF migrations, use [Program.CreateHostBuilder](xref:fundamentals/host/generic-host) to access the app's `IServiceProvider` to execute custom logic in the context of the app. These tools have been updated to use a new technique to execute custom logic in the context of the app. [Entity Framework Migrations](/ef/core/managing-schemas/migrations/) is an example of a tool that uses `Program.CreateHostBuilder`in this way. We're working to make sure tools are updated to use the new model.
* It's ***not*** possible to [change any host settings such as app name, environment, or the content root](xref:migration/50-to-60-samples#ccr) after the creation of the <xref:Microsoft.AspNetCore.Builder.WebApplicationBuilder>. See [Customize IHostBuilder or IWebHostBuilder](xref:migration/50-to-60-samples#cii) for detailed instructions on changing host settings. The following highlighted APIs throw an exception:
* Some tools, such as EF migrations, use [`Program.CreateHostBuilder`](xref:fundamentals/host/generic-host) to access the app's `IServiceProvider` to execute custom logic in the context of the app. These tools have been updated to use a new technique to execute custom logic in the context of the app. [Entity Framework Migrations](/ef/core/managing-schemas/migrations/) is an example of a tool that uses `Program.CreateHostBuilder`in this way. We're working to make sure tools are updated to use the new model.
* It's ***not*** possible to [change any host settings such as app name, environment, or the content root](xref:migration/50-to-60-samples#ccr) after the creation of the <xref:Microsoft.AspNetCore.Builder.WebApplicationBuilder>. For detailed instructions on changing host settings, see [Customize `IHostBuilder` or `IWebHostBuilder`](xref:migration/50-to-60-samples#cii). The following highlighted APIs throw an exception:

<!-- sample without try/catch
[!code-csharp[](50-to-60/samples/WebThrowEx/Program.cs?name=snippet1&highlight=5-14)]
Expand Down Expand Up @@ -158,43 +157,53 @@ The existing .NET ecosystem built extensibility around <xref:Microsoft.Extension

We expect library authors to continue targeting `IHostBuilder`, `IWebHostBuilder`, `IApplicationBuilder`, and `IEndpointRouteBuilder` when building ASP.NET Core specific components. This ensures that your middleware, route handler, or other extensibility points continue to work across different hosting models.

<h2 id="faq">Frequently asked questions (FAQ) </h2>
<h2 id="faq">Frequently asked questions (FAQ)</h2>

* **Is the new minimal hosting model less capable?**

No. The new hosting model is functionally equivalent for 98% of scenarios supported by `IHostBuilder` and the `IWebHostBuilder`. There are some advanced scenarios that require specific workarounds on `IHostBuilder`, but we expect those to be extremely rare.

### Is the new minimal hosting model less capable
* **Is the generic hosting model deprecated?**

No. The new hosting model is functionally equivalent for 98% of scenarios supported by `IHostBuilder` and the `IWebHostBuilder`. There are some advanced scenarios that require specific workarounds on `IHostBuilder`, but we expect those to be extremely rare.
No. The generic hosting model is an alternative model that is supported indefinitely. The generic host underpins the new hosting model and is still the primary way to host worker-based applications.

### Is the generic hosting model deprecated
* **Do I have to migrate to the new hosting model?**

No. The generic hosting model is an alternative model that is supported indefinitely. The generic host underpins the new hosting model and is still the primary way to host worker-based applications.
No. The new hosting model is the preferred way to host new apps using .NET 6 and later, but you aren't forced to change the project layout in existing apps. This means apps can upgrade from .NET 5 to .NET 6 by changing the target framework in the project file from `net5.0` to `net6.0`. For more information, see the [Update the target framework](#tf) section in this article. However, we recommend apps migrate to the new hosting model to take advantage of new features only available to the new hosting model.

### Do I have to migrate to the new hosting model
* **Do I have to use top-level statements?**

No. The new hosting model is the preferred way to host new apps using .NET 6 and later, but you aren't forced to change the project layout in existing apps. This means apps can upgrade from .NET 5 to .NET 6 by changing the target framework in the project file from `net5.0` to `net6.0`. See [Update the target framework](#tf) in this document. However, we recommend apps migrate to the new hosting model to take advantage of new features only available to the new hosting model.
No. The new project templates all use [top-level statements](/dotnet/csharp/fundamentals/program-structure/top-level-statements), but the new hosting APIs can be used in any .NET 6 app to host a webserver or web app.

### Do I have to use top-level statements
* **Where do I put state that was stored as fields in my `Program` or `Startup` class?**

No.
The new project templates all use [top-level statements](/dotnet/csharp/fundamentals/program-structure/top-level-statements), but the new hosting APIs can be used in any .NET 6 app to host a webserver or web app.
We strongly recommend using [dependency injection](xref:fundamentals/dependency-injection) (DI) to flow state in ASP.NET Core apps.

### Where do I put state that was stored as fields in my Program or Startup class
There are two approaches to storing state outside of DI:

We strongly recommend using [dependency injection](xref:fundamentals/dependency-injection) (DI) to flow state in ASP.NET Core apps.
* Store the state in another class. Storing in a class assumes a static state that can be accessed from anywhere in the app.
* Use the `Program` class generated by top level statements to store state. Using `Program` to store state is the semantic approach:

There are two approaches to storing state outside of DI:
[!code-csharp[](50-to-60/samples/WebThrowEx/Program.cs?name=snippetE)]

* Store the state in another class. Storing in a class assumes a static state that can be accessed from anywhere in the app.
* Use the `Program` class generated by top level statements to store state. Using `Program` to store state is the semantic approach:
* **What if I was using a custom dependency injection container?**

[!code-csharp[](50-to-60/samples/WebThrowEx/Program.cs?name=snippetE)]
Custom DI containers are supported. For an example, see [Custom dependency injection (DI) container](xref:migration/50-to-60-samples#cdi).

### What if I was using a custom dependency injection container
* **Do `WebApplicationFactory` and `TestServer` still work?**

Custom DI containers are supported. See [Custom dependency injection (DI) container](xref:migration/50-to-60-samples#cdi) for an example.
Yes. `WebApplicationFactory<TEntryPoint>` is the way to test the new hosting model. For an example, see [Test with `WebApplicationFactory` or `TestServer`](xref:migration/50-to-60-samples#twa).

### Does WebApplicationFactory and TestServer still work
## Blazor

`WebApplicationFactory<TEntryPoint>` is the way to test the new hosting model. See [Test with WebApplicationFactory or TestServer](xref:migration/50-to-60-samples#twa) for an example.
To adopt all of the new 6.0 features for Blazor apps, we recommend the following process:

* Create a new 6.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 6.0 app making modifications to adopt the new 6.0 features.

<!-- UNCOMMENT at 6.0 GA when the blog post is available. Confirm that the link text (title) and URL are correct ...
For more information on new Blazor features for 6.0, see [Announcing ASP.NET Core in .NET 6](https://devblogs.microsoft.com/aspnet/announcing-asp-net-core-in-net-6/).
-->

## Update Docker images

Expand Down Expand Up @@ -250,8 +259,25 @@ public DbSet<Key> Keys { get; set; }

## Codes samples migrated to ASP.NET Core 6.0

See <xref:migration/50-to-60-samples>
<xref:migration/50-to-60-samples>

## Review breaking changes

For breaking changes from .NET 5.0 to .NET 6.0, see [Breaking changes for migration from version 5.0 to 6.0](/dotnet/core/compatibility/6.0). ASP.NET Core and Entity Framework Core are also included in the list.
See the following resources:

* [Breaking changes for migration from version 5.0 to 6.0](/dotnet/core/compatibility/6.0): Includes ASP.NET Core and Entity Framework Core.
* [Announcements GitHub repository (aspnet/Announcements, `6.0.0` label)](https://github.com/aspnet/Announcements/issues?q=is%3Aissue+label%3A6.0.0+is%3Aopen): Includes breaking and non-breaking information.

## Nullable reference types (NRTs) and .NET compiler null-state static analysis

ASP.NET Core project templates use nullable reference types (NRTs), and the .NET compiler performs null-state static analysis. These features were released with C# 8 and are enabled by default for apps generated using ASP.NET Core 6.0 (C# 10) or later.

The .NET compiler's null-state static analysis warnings can either serve as a guide for updating a documentation example or sample app locally or be ignored. Null-state static analysis can be disabled by [setting `Nullable` to `disable`](/dotnet/csharp/language-reference/builtin-types/nullable-reference-types#setting-the-nullable-context) in the app's project file, which we only recommend for documentation examples and sample apps if the compiler warnings are distracting while learning about .NET. **_We don't recommended disabling null-state checking in production projects._**

For more information on NRTs, the MSBuild `Nullable` property, and updating apps (including `#pragma` guidance), see the following resources in the C# documentation:

* [Nullable reference types](/dotnet/csharp/nullable-references)
* [Nullable reference types (C# reference)](/dotnet/csharp/language-reference/builtin-types/nullable-reference-types)
* [Learn techniques to resolve nullable warnings](/dotnet/csharp/nullable-warnings)
* [Update a codebase with nullable reference types to improve null diagnostic warnings](/dotnet/csharp/nullable-migration-strategies)
* [Attributes for null-state static analysis](/dotnet/csharp/language-reference/attributes/nullable-analysis)