Please can the instructions for migrating .NET Core 2.2 to 3.0 be made clearer as this article contains a mixture of instructions, release notes and demos. Compared to the migration guide for .NET Core 2.1 > 2.2 it says it takes 4 times as long to read. All this document should contain are the steps required to migrate with the other information contained within other/further information pages.
By comparing a blank .NET Core 2.2 and 3.0 project and hitting issues/doing research I was able to work out the migration steps which are below in case anyone else finds them useful:
1. Copy Existing Project
Before starting it is worth taking a copy of your existing .NET Core 2.2 project as if anything goes wrong with the migration then you can always easily start again.
2. Delete Existing Published Files
After copying the project files, navigate to the project directory where the solution file is located and then into the sub-folder containing the project files.
Delete the following folders (renaming does not work as folders are still picked up and can cause issues due to conflicts with .NET Core 2.2):
bin
obj
3. Update the csproj file
Whilst still in the folder containing the project files, edit the .csproj file with any text editor.
Find the reference to the target framework:
<TargetFramework>netcoreapp2.2</TargetFramework>
Replace with:
<TargetFramework>netcoreapp3.0</TargetFramework>
Find the reference to the hosting model. If this is set to InProcess this section can be removed as this is now the default:
Remove any item groups relating to bundleconfig.json as this is no longer used (left over from .NET Core 2.1 I believe so this won't exist in newer projects).
Add the following packages so the section should now look like this (aside from any additional packages where it says <!-- Additional existing packages here -->:
Now save and close the csproj file and open your project with Visual Studio (.sln file in the top-level project folder)
Once you open the project again it is good practice to ensure any other packages you are using are up to date to ensure there are not compatibility issues with any other outdated packages.
Open the project and go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
On the updates tab, update any packages offered here.
4. Update Startup.cs
Open your project with Visual Studio (if not already open) and go to Startup.cs and find the following in the ConfigureServices section:
Also ensure the using command has been added at the top for Microsoft.Extensions.Hosting:
using Microsoft.Extensions.Hosting;
If you have this line in your project (added more recently in new .NET Core 2.2 projects) then remove the part in brackets as Bootstrap 4 is now the default so this is no longer declared here so find this:
.AddDefaultUI(UIFramework.Bootstrap4)
And replace with:
.AddDefaultUI()
If you have brought in the hosting environment into your startup function at the top this section will also require updating (this is not there by default in new projects but is often added as required at a later point). If not there then skip down to the next step.
Find the Startup function definition at the top:
public Startup(IConfiguration configuration, IHostingEnvironment env)
Replace it with
public Startup(IConfiguration configuration, IWebHostEnvironment env)
Below find the following:
public IHostingEnvironment HostingEnvironment { get; }
Replace with:
public IWebHostEnvironment HostingEnvironment { get; }
5. Update Program.cs
Open Program.cs from within Visual Studio.
Find the following in the Main function at the top:
CreateWebHostBuilder(args).Build().Run();
Replace with:
CreateHostBuilder(args).Build().Run();
Find the IWebHostBuilder fuction:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
If you set the web application to run on a specific port (if you are running multiple Kestrel web apps on the same Apache 2 Linux server) then ensure you also add back the line to specify the port number too. In this case the function would look like this (where xxxx is the port number as specified in your service file):
Also ensure the using command has been added at the top for Microsoft.Extensions.Hosting:
using Microsoft.Extensions.Hosting;
At this stage you may find your project will build
6. Build, Publish and Deploy
You should now be able to build, publish and deploy your project. The destination folder does now contain around 26 files whereas with .NET Core 2.2 it was around 9. A new runtimes folder is also now created.
If this fails try opening a CMD window and navigate to the project directory and run:
dotnet build
If you get an error about AspNetCore, Linq, Webpages (and various other commands) not being recognised then close all instances of Visual Studio and re-open your project again.
If you get the following error when attempting to publish:
Assets file '...\obj\project.assets.json' doesn't have a target for '.NETCoreApp,Version=v2.2'.
Ensure that restore has run and that you have included 'netcoreapp2.2' in the TargetFrameworks for your project.
Then go to Project Folder\Properties\PublishProfiles.
Edit FolderProfile.pubxml and look for
<TargetFramework>netcoreapp2.2</TargetFramework>
Replace with:
<TargetFramework>netcoreapp3.0</TargetFramework>
Sometimes this either fails to update itself or reverts back to 2.2 so even though on screen in the Publish section in VS it says target framework is netcoreapp3.0 it is actually trying to publish it as 2.2. This can happen when the project successfully published just minutes earlier.
The project should now work or if not you may need to follow the additional steps below:
6. Additional Migration Steps Depending on Code
JsonIgnore using Newtonsoft.Json
If you have used [JsonIgnore] on any of your class attributes to avoid circular references when generating Json this no longer works and is now has no effect.
The fix is to find instances of this:
using Newtonsoft.Json;
And replace with:
using System.Text.Json;
using System.Text.Json.Serialization;
Then it works again
Also if the Newtonsoft serializer is being referenced such as to specify the Json attributes then this will also need updating.
e.g. find this:
Stored Procedures
If you are calling stored procedures or executing SQL statements directly from code then you need to update the function that calls these as the name has changed:
In .NET Core 2.2 this works:
var surnameParam = new SqlParameter("@Surname", SqlDbType.NVarChar);
surnameParam.Value = (object)surname ?? DBNull.Value;
ObjectFromDB = await _context.ObjectFromDB
.FromSql("EXEC SPR_StoredProcedure @Surname", surnameParam)
.ToListAsync();
EF Core Queries
EF Core queries are now forced to execute on the server and not the client until after the entries have been converted to objects using ToListAsync(). This means anything that would have historically forced client-side execution now generates an error so this is now much more restrictive (in an attempt to always generate efficient SQL). Sometimes this may be a case of removing a .ToString() command or other times (for more complex statements) it may be easier to re-write as a stored procedure and execute that instead.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
ID: 76f39eec-9dd1-6167-56ec-47b26e0b5063
Version Independent ID: f9f2b0f3-01eb-cf58-8767-194fe0fc0e44
Please can the instructions for migrating .NET Core 2.2 to 3.0 be made clearer as this article contains a mixture of instructions, release notes and demos. Compared to the migration guide for .NET Core 2.1 > 2.2 it says it takes 4 times as long to read. All this document should contain are the steps required to migrate with the other information contained within other/further information pages.
By comparing a blank .NET Core 2.2 and 3.0 project and hitting issues/doing research I was able to work out the migration steps which are below in case anyone else finds them useful:
1. Copy Existing Project Before starting it is worth taking a copy of your existing .NET Core 2.2 project as if anything goes wrong with the migration then you can always easily start again.
2. Delete Existing Published Files After copying the project files, navigate to the project directory where the solution file is located and then into the sub-folder containing the project files. Delete the following folders (renaming does not work as folders are still picked up and can cause issues due to conflicts with .NET Core 2.2):
3. Update the csproj file Whilst still in the folder containing the project files, edit the .csproj file with any text editor.
Find the reference to the target framework:
Replace with:
Find the reference to the hosting model. If this is set to InProcess this section can be removed as this is now the default:
If it was the only entry in a
<PropertyGroup></PropertyGroup>
section then remove these two otherwise leave in place.Find and remove this line as this package is now split up into seperate packages to avoid duplication and ensure projects remain lean and efficient:
Also remove references to AspNetCore.Razor.Design (if it exists):
Remove any item groups relating to bundleconfig.json as this is no longer used (left over from .NET Core 2.1 I believe so this won't exist in newer projects).
Add the following packages so the section should now look like this (aside from any additional packages where it says
<!-- Additional existing packages here -->
:Now save and close the csproj file and open your project with Visual Studio (.sln file in the top-level project folder)
4. Update Startup.cs Open your project with Visual Studio (if not already open) and go to Startup.cs and find the following in the ConfigureServices section:
Replace with (compatibility version is no longer required):
Now move to the Configure section: Find the function definition:
Replace with:
Find:
Replace with:
Then update to this format:
Also ensure the using command has been added at the top for Microsoft.Extensions.Hosting:
If you have this line in your project (added more recently in new .NET Core 2.2 projects) then remove the part in brackets as Bootstrap 4 is now the default so this is no longer declared here so find this:
And replace with:
Find the Startup function definition at the top:
Replace it with
Below find the following:
Replace with:
5. Update Program.cs Open Program.cs from within Visual Studio.
Find the following in the Main function at the top:
Replace with:
Find the IWebHostBuilder fuction:
Replace with the new CreateHostBuilder function:
Also ensure the using command has been added at the top for Microsoft.Extensions.Hosting:
At this stage you may find your project will build
6. Build, Publish and Deploy You should now be able to build, publish and deploy your project. The destination folder does now contain around 26 files whereas with .NET Core 2.2 it was around 9. A new runtimes folder is also now created. If this fails try opening a CMD window and navigate to the project directory and run:
If you get an error about AspNetCore, Linq, Webpages (and various other commands) not being recognised then close all instances of Visual Studio and re-open your project again.
If you get the following error when attempting to publish:
Then go to Project Folder\Properties\PublishProfiles.
Edit
FolderProfile.pubxml
and look forReplace with:
The project should now work or if not you may need to follow the additional steps below:
6. Additional Migration Steps Depending on Code
JsonIgnore using Newtonsoft.Json If you have used
[JsonIgnore]
on any of your class attributes to avoid circular references when generating Json this no longer works and is now has no effect.The fix is to find instances of this:
And replace with:
Then it works again
Also if the Newtonsoft serializer is being referenced such as to specify the Json attributes then this will also need updating. e.g. find this:
Replace with:
Stored Procedures If you are calling stored procedures or executing SQL statements directly from code then you need to update the function that calls these as the name has changed:
In .NET Core 2.2 this works:
In .NET Core 3.0 you must do this instead:
SQL procedures that are executed but do not return a list also need to be updated from:
To:
Also
FirstOrDefaultAsync()
now also generates an error in .NET Core 3.0 with stored procedures as evaluates queries incorrectly.e.g. this command:
Is now incorrectly sent to SQL Server as:
So the command must be wrapped in a
ToListAsync()
then it is correctly handled:EF Core Queries EF Core queries are now forced to execute on the server and not the client until after the entries have been converted to objects using
ToListAsync()
. This means anything that would have historically forced client-side execution now generates an error so this is now much more restrictive (in an attempt to always generate efficient SQL). Sometimes this may be a case of removing a.ToString()
command or other times (for more complex statements) it may be easier to re-write as a stored procedure and execute that instead.Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.