Migrate from ASP.NET Core 2.1 to 2.2
By Scott Addie
This article explains how to update an existing ASP.NET Core 2.1 project to ASP.NET Core 2.2.
Prerequisites
- Visual Studio 2019 with the ASP.NET and web development workload
- .NET Core SDK 2.2 or later
Warning
If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.
Update Target Framework Moniker (TFM)
Projects targeting .NET Core should use the TFM of a version greater than or equal to .NET Core 2.2. In the project file, update the <TargetFramework>
node's inner text with netcoreapp2.2
:
<TargetFramework>netcoreapp2.2</TargetFramework>
Projects targeting .NET Framework may continue to use the TFM of a version greater than or equal to .NET Framework 4.6.1:
<TargetFramework>net461</TargetFramework>
Adopt the IIS in-process hosting model
To adopt the in-process hosting model for IIS, add the <AspNetCoreHostingModel>
property with a value of InProcess
to a <PropertyGroup>
in the project file:
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
The in-process hosting model isn't supported for ASP.NET Core apps targeting .NET Framework.
For more information, see ASP.NET Core Module (ANCM) for IIS.
Update a custom web.config file
For projects that use a custom web.config file in the project root to generate their published web.config file:
- In the
<handlers>
entry that adds the ASP.NET Core Module (name="aspNetCore"
), change themodules
attribute value fromAspNetCoreModule
toAspNetCoreModuleV2
. - In the
<aspNetCore>
element, add the hosting model attribute (hostingModel="InProcess"
).
For more information and example web.config files, see ASP.NET Core Module (ANCM) for IIS.
Update package references
If targeting .NET Core, remove the metapackage reference's Version
attribute in the project file. Inclusion of a Version
attribute results in the following warning:
A PackageReference to 'Microsoft.AspNetCore.App' specified a Version of `2.2.0`. Specifying the version of this package is not recommended. For more information, see https://aka.ms/sdkimplicitrefs
For more information, see Microsoft.AspNetCore.App metapackage for ASP.NET Core.
The metapackage reference should resemble the following <PackageReference />
node:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
If targeting .NET Framework, update each package reference's Version
attribute to 2.2.0 or later. Here are the package references in a typical ASP.NET Core 2.2 project targeting .NET Framework:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
</ItemGroup>
If referencing the Microsoft.AspNetCore.Razor.Design package, update its Version
attribute to 2.2.0 or later. Failure to do so results in the following error:
Detected package downgrade: Microsoft.AspNetCore.Razor.Design from 2.2.0 to 2.1.2. Reference the package directly from the project to select a different version.
Update .NET Core SDK version in global.json
If your solution relies upon a global.json file to target a specific .NET Core SDK version, update its version
property to the 2.2 version installed on your machine:
{
"sdk": {
"version": "2.2.100"
}
}
Update launch settings
If using Visual Studio Code, update the project's launch settings file (.vscode/launch.json
). The program
path should reference the new TFM:
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/netcoreapp2.2/test-app.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
Update Kestrel configuration
If the app calls UseKestrel by calling CreateDefaultBuilder
in the CreateWebHostBuilder method of the Program
class, call ConfigureKestrel
to configure Kestrel server instead of UseKestrel
in order to avoid conflicts with the IIS in-process hosting model:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
// Set properties and call methods on options
});
If the app doesn't call CreateDefaultBuilder
and builds the host manually in the Program
class, call UseKestrel before calling ConfigureKestrel
:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>
{
// Set properties and call methods on options
})
.Build();
host.Run();
}
For more information, see Kestrel web server in ASP.NET Core.
Update compatibility version
Update the compatibility version in Startup.ConfigureServices
to Version_2_2
:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
Update CORS policy
In ASP.NET Core 2.2, the CORS middleware responds with a wildcard origin (*
) if a policy allows any origin and allows credentials. Credentials aren't supported when a wildcard origin (*
) is specified, and browsers will disallow the CORS request. For more information, including options for correcting the problem on the client, see the MDN web docs.
To correct this problem on the server, take one of the following actions:
- Modify the CORS policy to no longer allow credentials. That is, remove the call to AllowCredentials when configuring the policy.
- If credentials are required for the CORS request to succeed, modify the policy to specify allowed hosts. For example, use
builder.WithOrigins("https://api.example1.com", "https://example2.com")
instead of using AllowAnyOrigin.
Update Docker images
The following table shows the Docker image tag changes:
2.1 | 2.2 |
---|---|
microsoft/dotnet:2.1-aspnetcore-runtime |
mcr.microsoft.com/dotnet/core/aspnet:2.2 |
microsoft/dotnet:2.1-sdk |
mcr.microsoft.com/dotnet/core/sdk:2.2 |
Change the FROM
lines in your Dockerfile to use the new image tags in the preceding table's 2.2 column.
Build manually in Visual Studio when using IIS in-process hosting
Visual Studio's Auto build on browser request experience doesn't function with the IIS in-process hosting model. You must manually rebuild the project when using in-process hosting. Improvements to this experience are planned for a future release of Visual Studio.
Update logging code
Recommended logging configuration code didn't change from 2.1 to 2.2, but some 1.x coding patterns that still worked in 2.1 no longer work in 2.2.
If your app does logging provider initialization, filtering, and configuration loading in the Startup
class, move that code to Program.Main
:
Provider initialization:
1.x example:
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); }
2.2 example:
public static void Main(string[] args) { var webHost = new WebHostBuilder() // ... .ConfigureLogging((hostingContext, logging) => { logging.AddConsole(); }) // ... }
Filtering:
1.x example:
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(LogLevel.Information); // or loggerFactory.AddConsole((category, level) => category == "A" || level == LogLevel.Critical); }
2.2 example:
public static void Main(string[] args) { var webHost = new WebHostBuilder() // ... .ConfigureLogging((hostingContext, logging) => { logging.AddConsole() .AddFilter<ConsoleLoggerProvider> (category: null, level: LogLevel.Information) // or .AddFilter<ConsoleLoggerProvider> ((category, level) => category == "A" || level == LogLevel.Critical) ); }) // ... }
Configuration loading:
1.x example:
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration); }
2.2 example:
public static void Main(string[] args) { var webHost = new WebHostBuilder() // ... .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); }) // ... }
For more information, see Logging in .NET Core and ASP.NET Core
ASP.NET Core Module (ANCM)
If the ASP.NET Core Module (ANCM) wasn't a selected component when Visual Studio was installed or if a prior version of the ANCM was installed on the system, download the latest .NET Core Hosting Bundle Installer (direct download) and run the installer. For more information, see Hosting Bundle.