Skip to content
MERVENORBook a triage call

Guide · .NET Framework migration

Moving from .NET Framework to modern .NET, step by step

By MervenorPublished Last reviewed 5 min read

In short

Do not rewrite: move the application across in slices while it stays in production. Put a new ASP.NET Core application in front of the old one, move routes across one group at a time, and switch the old host off only when nothing is left behind it. Target .NET 10, the current long-term-support release, supported until 14 November 2028.

Before you start

.NET Framework 4.8.1 is still supported as part of Windows, but it gets no new features, and many libraries have moved on. Modern .NET, the platform that began as .NET Core, ships a new version every year: long-term-support (LTS) releases get three years of fixes, standard-term releases two. Microsoft set 10 November 2026 as the end of support for both .NET 8 and .NET 9, so a migration started now should target .NET 10.

Step 1: Take an inventory

List every project and its target framework, every NuGet package (and whether a modern version exists), every use of System.Web, every Windows-only dependency (COM, the registry, Windows services, reporting and PDF libraries), the configuration in web.config, the authentication model, and how the application is built and deployed.

Microsoft's tooling helps here. The .NET Upgrade Assistant is now deprecated; Microsoft points to the GitHub Copilot modernization agent in Visual Studio, which analyses projects and dependencies, proposes a plan and automates mechanical fixes, committing each change so it can be reviewed or rolled back. Use it for the mechanical work. The decisions (what to port, what to replace, what to leave) still need someone who has read the code.

Step 2: Clear the blockers first

Microsoft's incremental-migration guide recommends paying down the debt that makes the move harder before moving anything: update NuGet packages one at a time, convert projects to the SDK style with PackageReference, and fix warnings and deprecated API calls. Each of these is safe to ship on .NET Framework, so the old application keeps running throughout.

Step 3: Share the core

Class libraries come next. Make them multi-target (for example net48 and net10.0) or move them to .NET Standard 2.0 so both the old and the new application can use them. Work from the leaves of the dependency tree upwards; Microsoft's guidance is that the main ASP.NET application should be the last thing to change.

Step 4: Put a new ASP.NET Core application in front

Create an ASP.NET Core application that sits in front of the old one and forwards every request it does not handle yet, using the YARP reverse proxy. Users see one website throughout. The Microsoft.AspNetCore.SystemWebAdapters package lets the two applications share session state and sign-in during the move, so nobody is logged out when a page changes hands, and lets shared libraries keep using HttpContext while they are migrated.

Step 5: Move routes in slices

Start with simple, stateless endpoints, as Microsoft recommends. For each slice:

  1. Write tests that capture what the route does today (characterisation tests), including its URLs, responses and errors.
  2. Port the controller, filters and dependency registration to ASP.NET Core.
  3. Switch the route in the proxy, deploy and watch the monitoring.
  4. Keep the way back: if anything misbehaves, route the slice back to the old application.

Search rankings move with you as long as every URL keeps responding in the same place; where a URL must change, add a permanent redirect in the same release.

Step 6: Move data access and identity

Entity Framework 6 can run on modern .NET as an interim step, so data access does not have to move in the same slice as the web layer. Move to EF Core query by query, comparing results against the old code on a copy of production data. Plan the identity migration on its own: ASP.NET Membership or Identity 2 users move to ASP.NET Core Identity, and password hashes, cookie names and sign-in redirects all need a deliberate decision.

Step 7: Retire the old host

Switch the .NET Framework application off only when every route has moved and monitoring has been quiet for an agreed period. Then remove the proxy rules, archive the old deployment, and decide on hosting: Linux containers usually cost less to run, and Windows with IIS remains a valid choice.

Questions people ask

  1. Should we migrate to .NET 8 or .NET 10?

    .NET 10. Microsoft set 10 November 2026 as the end of support for .NET 8 and recommends .NET 10, a long-term-support release supported until 14 November 2028.

  2. Is there a tool that does the whole migration?

    No. The Copilot modernization agent and the compatibility analysers handle mechanical changes and report blockers; they do not migrate WebForms, redesign authentication or choose hosting.

  3. What about WebForms and WCF?

    They have no direct port. The guide to the hard parts covers the options.

  4. How long does it take?

    It depends on the number of projects, how much WebForms and WCF there is, and how much is covered by tests. A single application with a clean structure moves in weeks; an estate of several services is phased, with something shippable after each phase.

If this is your application

Renascia, the upgrade and migration sprint, moves .NET Framework applications to .NET 10 in slices like these, at a fixed price set by a five-day Perlustra audit.

.NET Framework migration

01Start

Tell us about the application

Thirty minutes, no slides, no sales script. You leave with a view on what to check first.

Length
30 minutes
Cost
Free
You leave with
A view on what to check first