Over the past year or so Ive been part of a large-ish modernization effort, both migrating from .NET 4.8 to .NET 6 (the latest LTS at the time) and from an on-premise deployment to Azure. While these two workstreams were largely independent (luckily), we did have some dependencies between the two efforts. There are quite a few how-to articles on the more vanilla aspects of migration but I wanted to walk through a few more of the...messy aspects of migration that crop up when youve got a codebase thats been around for over a decade. This isnt the first codebase Ive migrated from .NET Framework to .NET...Core? BUT its luckily a lot easier than it used to be. As a general strategy for modernization of any codebase, I vastly prefer the Strangler Fig pattern, incrementally migrating from the legacy application to the modern one, until the legacy application is retired. Or whatever portions we want to modernize are at least! This greatly reduces the risks over a big-bang migration, which I almost never see succeed. When we first started examining migration techniques in the second half of 2022, Microsoft had released their preview of a set of tools and libraries that allow for incremental migration, making the Strangler Fig strategy MUCH easier to implement. The general idea behind the System.Web Adapters starts with YARP, a reverse proxy hosted in a .NET 6 application. We start with our normal application. Next we add the System.Web Adapters and its reverse proxy to a blank application. External requests go to this initial application instead of the .NET 4.8 web application. If the .NET (6/7/8) application cant handle the request, the self-hosted reverse proxy forwards that request to your .NET 4.8 application. Any shared logic well need to refactor into common library(ies). Next, we migrate pages/controllers over to the .NET Core app. The other piece the library provides are adapters for the legacy System.Web references, where your existing code that uses say System.Web.HttpContext will transparently forward those calls into the correct .NET Core libraries. Eventually, all of the requests are handled by the ASP.NET Core application and we can safely remove the .NET Framework application. Sounds easy, right? Wellll we found in practice that there are lots of little decisions and roadblocks along the way. From 3rd-party libraries, to un-migrateable code, to missing features, we had all sorts of challenges along the way. Nothing was insurmountable and we went live in Azure and converted from .NET 6 a little over 4 months after starting with very few issues after flipping the switch. In this series, Ill walk through our entire process along the way, from analysis to production. Sign up for more like this. Enter your email. Subscribe.