Incremental ASP.NET to ASP.NET Core migration

Migrating an app from ASP.NET Framework to ASP.NET Core is non-trivial for the majority of production apps. These apps often incorporate new technologies as they become available and are often composed of many legacy decisions. This article provides guidance and links to tools for migrating ASP.NET Framework apps to ASP.NET Core with as little change as possible.

One of the larger challenges is the pervasive use of HttpContext throughout a code base. Without the incremental approach and tools, a large scale rewrite is required to remove the System.Web.HttpContext dependency. The adapters in dotnet/systemweb-adapters provide a set of runtime helpers to access the types used in the ASP.NET Framework app in a way that works in ASP.NET Core with minimal changes.

A complete migration may take considerable effort depending on the size of the app, dependencies, and non-portable APIs used. In order to keep deploying an app to production while working on migrating, the best pattern is to follow is the Strangler Fig pattern. The Strangler Fig pattern allows for continual development on the old system with an incremental approach to replacing specific pieces of functionality with new services. This document describes how to apply the Strangler Fig pattern to an ASP.NET app migrating towards ASP.NET Core.

If you'd like to skip this overview article and get started, see Get started.

App migration to ASP.NET Core

Before starting the migration, the app targets ASP.NET Framework and runs on Windows with its supporting libraries:

Before starting the migration

Migration starts by introducing a new app based on ASP.NET Core that becomes the entry point. Incoming requests go to the ASP.NET Core app, which either handles the request or proxies the request to the .NET Framework app via YARP. At first, the majority of code providing responses is in the .NET Framework app, but the ASP.NET Core app is now set up to start migrating routes:

start migrating routes

To migrate business logic that relies on HttpContext, the libraries need to be built with Microsoft.AspNetCore.SystemWebAdapters. Building the libraries with Microsoft.AspNetCore.SystemWebAdapters allows:

  • The libraries to be built against .NET Framework, .NET Core, or .NET Standard 2.0.
  • Ensures that the libraries are using APIs that are available on both ASP.NET Framework and ASP.NET Core.

Microsoft.AspNetCore.SystemWebAdapters

Once the ASP.NET Core app using YARP is set up, you can start migrating routes from ASP.NET Framework to ASP.NET Core. For example, WebAPI or MVC controller action methods,handlers, or some other implementation of a route. If the route is available in the ASP.NET Core app, it's matched and served.

During the migration process, additional services and infrastructure are identified that must be migrated to run on .NET Core. Options listed in order of maintainability include:

  1. Move the code to shared libraries
  2. Link the code in the new project
  3. Duplicate the code

Eventually, the ASP.NET Core app handles more of the routes than the .NET Framework app:

the ASP.NET Core app handles more of the routes

Once the ASP.NET Framework app is no longer needed and deleted:

  • The app is running on the ASP.NET Core app stack, but is still using the adapters.
  • The remaining migration work is removing the use of adapters.

final pic

Microsoft Project Migrations is an experimental Visual Studio extension that can assist in incremental migration from ASP.NET Framework to ASP.NET Core.

System.Web Adapters

The Microsoft.AspNetCore.SystemWebAdapters namespace is a collection of runtime helpers that facilitate using code written against System.Web while moving to ASP.NET Core. There are a few packages that may be used to use features from these adapters:

  • Microsoft.AspNetCore.SystemWebAdapters: This package is used in supporting libraries and provide the System.Web APIs you may have taken a dependency on, such as HttpContext and others. This package targets .NET Standard 2.0, .NET 4.5+, and .NET 6+.
  • Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices: This package only targets .NET Framework and is intended to provide services to ASP.NET Framework applications that may need to provide incremental migrations. This is generally not expected to be referenced from libraries, but rather from the applications themselves.
  • Microsoft.AspNetCore.SystemWebAdapters.CoreServices: This package only targets .NET 6+ and is intended to provide services to ASP.NET Core applications to configure behavior of System.Web APIs as well as opting into any behaviors for incremental migration. This is generally not expected to be referenced from libraries, but rather from the applications themselves.
  • Microsoft.AspNetCore.SystemWebAdapters.Abstractions: This package is a supporting package that provides abstractions for services used by both the ASP.NET Core and ASP.NET Framework application such as session state serialization.

For examples of scenarios where this is useful, see the adapters article.

For guidance around usage, see the usage guidance article.

Additional Resources