On September 23rd .NET Core 3.0 was released including ASP.NET Core 3.0 and Entity Framework Core 3.0. This post will be taking the Contacts project used in the ASP.NET Basics series and migrating it from .NET Core 2.2 to .NET Core 3.0. Most of the information used for this migration comes from the Microsoft docs which will cover way more scenarios than this post will.
The code before any changes can be found in this GitHub repo. A reminder that the Contacts project is the only project being updated with this post the projects in the repo will remain on ASP.NET Core 2.2 for now.
Installation
If you are a Visual Studio user you can get .NET Core 3.0 by installing at least Visual Studio 16.3. For those not using Visual Studio, you can download and install .NET Core 3.0 SDK from here. As with previous versions, the SDK is available for Windows, Linux, and Mac.
After installation is complete you can runt the following command from a command prompt to see all the versions of the .NET Core SDK you have installed.
dotnet --list-sdks
You should see 3.0.100 listed. If you are like me you might also see a few preview versions of the SDK that can be uninstalled at this point.
Project File Changes
Right-click on the project and select Edit projectName.csproj.
Change the TargetFramework to netcoreapp3.0.
Before:
<TargetFramework>netcoreapp2.2</TargetFramework>
After:
<TargetFramework>netcoreapp3.0</TargetFramework>
The packages section has a lot of changes. Microsoft.AspNetCore.App is now gone and part of .NET Core without needing a specific reference. The other thing to note is that Entity Framework Core is no longer “in the box” so you will see a lot of references add to make Entity Framework Core usable.
Before:
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
After:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
The last thing to note is that Swashbuckle doesn’t have a final version ready for .NET Core 3 so you will have to make sure you are using version 5 rc2 at a minimum.
The following is my full project file for reference.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<UserSecretsId>aspnet-Contacts-cd2c7b27-e79c-43c7-b3ef-1ecb04374b70</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
</ItemGroup>
</Project>
Program Changes
In Program.cs some changes to the way the host is constructed. The over version may or may not have worked, but I created a new app and pulled this out of it just to make sure I’m using the current set up.
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Contacts
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Startup Changes
In Startup.cs we have quite a few changes to make. As long as you haven’t do any customization in the constructor you can replace it with the following.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
Next, they type on the configuration property changed from IConfigurationRoot to IConfiguration.
Before:
public IConfigurationRoot Configuration { get; }
After:
public IConfiguration Configuration { get; }
Moving on to the ConfigureServices function has a couple of changes to make. The first is a result of updating to the newer version of the Swagger package where the Info class has been replaced with OpenApiInfo.
Before:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "Contacts API", Version = "v1"});
});
After:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Contacts API", Version = "v1" })
});
Next, we are going to move from using UserMvc to the new AddControllersWithViews which is one of the new more targeted ways to add just the bits of the framework you need.
Before:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
After:
services.AddControllersWithViews();
Now in the Configure function, the function signature needs to be updated and the logging factory bits removed. If you do need to configure logging that should be handled as part of the HostBuilder.
Before:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
After:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
For the next set of changes, I’m just going to show the result and not the before. The UseCors may or may not apply but the addition of UserRouting and the replacement of UseMvc with UserEndpoint will if you want to use the new endpoint routing features.
app.UseStaticFiles();
app.UseRouting();
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.AllowAnyOrigin();
}
);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
Other Miscellaneous Changes
The only other change I had was the removal of @using Microsoft.AspNetCore.Http.Authentication
in a few cshtml files related to login.
Wrapping Up
The migration from 2.2 to 3.0 is a bit more involved than the move from 2.1 to 2.2, but that isn’t surprising with all the changes in this release. Remember to check out the official migration guide for more details.
The code for the Contacts project after the above changes can be found on GitHub.