There's not 1 single thing that makes a .NET project complex to migrate to the latest .NET Framework. Generally though it's a combination of the following:
If your project doesn't meet any of the above criteria, you should consider using the .NET Upgrade Assistant. You can read more about the tool at Do you know how to modernize your .NET applications? If the .NET Upgrade Assistant works for your project, you could save a significant amount of time. However, the level of success may vary across different projects.
While complex .NET migration has many steps and can be time-consuming, it offers significant benefits, including incremental migrations, improved risk management, and streamlined progress tracking.
The migration begins with an Evolutionary approach and then smoothly transitions to the Strangler Fig pattern, optimizing the advantages of both approaches. The Evolutionary approach ensures better compatibility with .NET 8 for the existing code, while the Strangler Fig pattern complete the full migration.
This strategy results in a codebase that functions within the old .NET Framework while progressively moving towards .NET 8. The majority of changes bring benefits to both platforms, allowing seamless deployment of these improvements to production. You can get more information about different migration approaches at Do you know the different ways to modernize your application?
Below you will find some tips and tricks to help you with your more complex migrations.
You can use the try-convert dotnet tool to convert your projects to the new sdk style csproj format. This will make it easier to upgrade the projects to the latest .NET Framework.
Install the tool using
dotnet tool install -g try-convert
Upgrade your web projects using
try-convert --keep-current-tfms --force-web-conversion
and your other projects using
try-convert --keep-current-tfms
In all your project files change the TargetFramework to TargetFrameworks. You want to do this early on to enable a smoother flow later to not need unload and reload projects or have to close and reopen Visual Studio.
What this will allow you to do is add your target framework and compile the code. This will allow you to see what code is not compatible with the new framework and fix those issues while still developing/deploying your project in the current target framework.
<TargetFrameworks>net472;net8.0</TargetFrameworks>
Figure: Git changes for targeting to multiple target frameworks
At this point, ensure your project can target both the .NET Framework and the new target .NET. Some of the projects might not support both platforms right away and you can follow these steps to fix the issues and have a better understanding of how much work it might lies ahead.
Outlined below are rules designed to assist in the project upgrade process during migration. Please note that the applicability of certain rules may vary based on individual project requirements.
There are several ways to migrate projects from ASP.NET to ASP.NET Core. We strongly recommend using the Strangler Fig pattern to incrementally migrate your project with YARP.
After you've installed the .NET Upgrade Assistant extension, Right-click on the project in the Solution Explorer window, and select Upgrade.
Figure: Visual Studio context menu.
A tab is opened which provides, based on your project type, different styles of upgrade:
On more complex projects you might find that Upgrade Assistant only provides you with the side-by-side incremental option. That is also the option that is covered here.
Once your app has been upgraded, a status screen is displayed which shows all of the artifacts related to your project that were associated with the upgrade. Each upgrade artifact can be expanded to read more information about the status. The following list describes the status icons:
Figure: Example results from an Upgrade Assistant upgrade.
After the Upgrade Assistant completes the upgrade you will find a new project in the solution running .NET 8. Upgrade Assistant pre-configured the project and installed any necessary packages it required to run side-by-side using the Yarp proxy.
Figure: The new project architecture and request flow.
As you can see in the above diagram, we want our UI to go through the .NET 8 project where the Yarp Proxy will either serve and fulfill the request or pass it through to the legacy project.
When you look at the Program.cs in the newly created .NET 8 project, you will see that there is a configuration for the catch-all forwarder. You will need to update the configuration here with the address of your legacy project.
var app = builder.Build();if (!app.Environment.IsDevelopment()){app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseSystemWebAdapters();app.MapDefaultControllerRoute();// This is responsible that requests are forwarded// You need to change the configuration for ProxyTo to// your legacy project's addressapp.MapForwarder("/{**catch-all}", app.Configuration["ProxyTo"]).Add(static builder => ((RouteEndpointBuilder)builder).Order = int.MaxValue);app.Run();
Figure: Program.cs code showing the forward clause to the legacy project
Once you have created the side-by-side project, select the project that needs migration and right click | Upgrade on it.
Figure: Context menu on the project to be migrated.
Upgrade Assistant will show you a Summary view and detect that the project is linked to your Yarp proxy. You can also see the migration progress of your endpoints from .NET Framework to .NET as a pie chart.
Figure: Upgrade Assistant's Summary page.
From here you can explore your endpoints through the Endpoint explorer, which will also indicate what endpoints have already been migrated and which ones are still outstanding.
The chain icon indicates that this endpoint has been migrated and is linked between the controller in the old project and the controller in the Yarp proxy project.
Figure: Chain Icon
Figure: Endpoint Explorer showing the endoints between the old .NET Framework project and the new .NET Core project.
Use the Upgrade functionality to apply automatic code transformations and speed up the migration process.
In the best-case scenario, the controller has been fully ported across and does not require any manual work.
In most scenarios, you will need to review the controller and update any custom code that the Upgrade Assistant could not automatically transform.
Figure: Upgrade Assistant progress upgrading a controller.
When a web project is heavily reliant on .NET Framework dependencies, the first step in gauging the effort required for a complete migration is to thoroughly examine these dependencies. This involves a detailed investigation, followed by the creation of PBIs for each dependency. These PBIs serve to accurately scope out the total effort that will be needed for the migration process.
Listed below are rules crafted to aid in the project migration process. Please ensure to incorporate only those rules that are applicable to your specific project.
By now, you should have wrapped up the entire migration including the web applications. It's the perfect moment to use the .NET Upgrade Assistant. It'll guide you in cleaning up the codebase. The ultimate goal is to eliminate all the old .NET Framework components and keep only the code and the most up-to-date NuGet packages for .NET 8.