On August 14th .NET Core 2.0 was released including corresponding versions of ASP.NET Core 2.0 and Entity Framework Core 2.0 which got with the finalization of .NET Standard 2.0. The links take you to the release notes for each item.
In this post, I will be covering taking the project used for the ASP.NET Basics series from 1.1.x to the 2.0 release. The starting point of the code can be found here. This post is only going to cover conversion of the Contacts project.
Installation
If you are a Visual Studio user make sure you have the latest version of Visual Studio 2017, which can be found here and at a minimum should be version 15.3.
Next, install the SDK for your operating system. The list of installs can be found here. For development, it is key that you install the SDK, not just the runtime. The following is a preview of what to expect on the download page.
Csproj
The csproj file of the project being upgraded is the best place to start the conversion. The TargetFramework needs to be changed to 2.0.
Before:
<TargetFramework>netcoreapp1.1</TargetFramework>
After:
<TargetFramework>netcoreapp2.0</TargetFramework>
Next, PackageTargetFallback changed to AssetTargetFallback.
Before:
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
After:
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81</AssetTargetFallback>
There is a new Microsoft.AspNetCore.All package that bundles up what used to be a huge list of individual packages. Those individual packages still exist, but this new one wraps them and makes it much easier to get started. The following is the package list before and after.
Before:
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.0" />
After:
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
Last change in this file is to change the DotNetCliToolReference versions to 2.0.0.
Before:
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
After:
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
Program.cs
Program.cs is another area that has been simplified by creating a default builder that does all the same things that were happening before but hide the details. Keep in mind the old version still works and is valid to use if you use case needs it.
Before:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
After:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
Identity
The remaining changes I had to make were all related to Identity. In the Startup class’s Configure function the following change was needed.
Before:
app.UseIdentity();
After:
app.UseAuthentication();
Next, in the ManageLoginsViewModel class, the type of the OtherLogins property changed.
Before:
public IList<AuthenticationDescription> OtherLogins { get; set; }
After:
public IList<AuthenticationScheme> OtherLogins { get; set; }
The SignInManager dropped the GetExternalAuthenticationSchemes function in favor of GetExternalAuthenticationSchemesAsync. This caused changes in a couple of files. First, in the ManageController the following change was made.
Before:
var otherLogins = _signInManager
.GetExternalAuthenticationSchemes()
.Where(auth => userLogins
.All(ul => auth.AuthenticationScheme != ul.LoginProvider))
.ToList();
After:
var otherLogins = (await _signInManager
.GetExternalAuthenticationSchemesAsync())
.Where(auth => userLogins
.All(ul => auth.Name != ul.LoginProvider))
.ToList();
The second set of changes were in the Login.cshtml file. First the function change.
Before:
var loginProviders = SignInManager.GetExternalAuthenticationSchemes().ToList();
After:
var loginProviders = (await SignInManager.GetExternalAuthenticationSchemesAsync()).ToList();
Then the change to deal with the changed property names.
Before:
<button type="submit" class="btn btn-default"
name="provider" value="@provider.AuthenticationScheme"
title="Log in using your @provider.DisplayName account">
@provider.AuthenticationScheme
</button>
After:
<button type="submit" class="btn btn-default"
name="provider" value="@provider.Name"
title="Log in using your @provider.DisplayName account">
@provider.Name
</button>
Wrapping up
With the changes in the Contacts project now works on ASP.NET Core 2.0! Make sure to check out Microsoft’s regular migration guide. as well as their identity migration guide. A full list of breaking changes for this release can be found here.
There is a lot more to explore with this new release and I have a lot of projects to update. Don’t worry I won’t be doing a blog post on all of them, but if I do hit any issues I will create a new post of update this one with the fixes. The finished code can be found here.