ASP.NET Web Forms on .NET 8 or 10: what the options are

ASP.NET Web Forms ships with the .NET Framework and has no counterpart in ASP.NET Core. An application built on it can still get to .NET 8 or 10; changing the target framework alone will not do it. Here are the routes and how to tell which one fits your application.

Where things stand

Microsoft’s book “Blazor for ASP.NET Web Forms developers” says: “The .NET team made it clear that ASP.NET Web Forms won’t be ported to .NET Core or .NET 8.” The same page says: “As long as the .NET Framework ships as part of Windows, ASP.NET Web Forms will be a supported framework.”

That support comes from Windows. Microsoft’s lifecycle FAQ: “Beginning with version 4.5.2 and later, .NET Framework is defined as a component of the Windows operating system (OS). Components receive the same support as their parent products, therefore, .NET Framework 4.5.2 and later follows the lifecycle policy of the underlying Windows OS on which it is installed.” In the post that announced .NET Core as the future of .NET, Microsoft wrote that 4.8 is the last major version of .NET Framework and that “We will continue to both service and support .NET Framework.”

An application leaves Web Forms because of what it cannot get there. New runtime features, hosting on Linux and in containers, and new library versions go to .NET 8 and later, and a Web Forms project cannot follow on its own.

Option 1: stay on .NET Framework and move everything around it

This is the right choice when the application works, changes rarely and runs on Windows servers that are staying. Microsoft’s book says the same: “If you don’t have a requirement for cross-platform support, open-source, or any of the other new features in .NET Core or .NET 8, then sticking with ASP.NET Web Forms on Windows is fine.”

The rest of the solution can still move. Class libraries can target .NET Standard 2.0 and be shared by the Web Forms project and by new .NET 8 or 10 services. Windows services, console jobs, WCF and Web API back ends can move one at a time. The Web Forms project becomes a thin UI over code that already runs on modern .NET, and a later UI rewrite has less to carry. The same work is the first stage of every option below.

Option 2: Microsoft’s incremental migration (System.Web adapters and YARP)

For a large ASP.NET Framework application Microsoft recommends an incremental migration: a new ASP.NET Core application is put in front of the old one and proxies to it with YARP. In Microsoft’s words, “Local routes take precedence” and “Unmatched requests are automatically forwarded to the ASP.NET Framework application.” Both applications run at the same time, and users reach them through one address.

The Microsoft.AspNetCore.SystemWebAdapters package, from the dotnet/systemweb-adapters ↗ repository, gives class libraries a System.Web.HttpContext that works on both sides, so a library compiled for .NET Standard 2.0 can be called from the old application and from the new one. The FrameworkServices and CoreServices packages add remote session state (the .NET Framework application serves session data to the ASP.NET Core application through an endpoint) and remote authentication (the ASP.NET Core application defers sign-in to the old one). HTTP modules that cannot easily become middleware can be registered in ASP.NET Core through the same adapters.

The adapters do not run an .aspx page on ASP.NET Core. They cover HttpContext, session, authentication and modules. The Web Forms pages themselves stay in the .NET Framework application behind the proxy until each one is rewritten as an MVC view, a Razor Page or a Blazor component. For a Web Forms application the incremental path lets you move page by page while the site stays in production, and each page is still rewritten.

Option 3: rewrite the UI in Blazor

Blazor is where Microsoft points Web Forms developers: for Web Forms “we would recommend Blazor which provides the closest programming model”. The book “Blazor for ASP.NET Web Forms developers” goes through the concepts side by side. The main mappings:

Web FormsBlazor
.aspx page with code-behind.razor component; markup and code in one file, or a partial class as code-behind
.ascx user control, server controlComponent with [Parameter] properties; RenderFragment for templated controls such as Repeater
Page_Init, Page_Load, PreRender, UnloadOnInitialized, OnParametersSet, OnAfterRender, IDisposable; the book likens OnInitialized to Page_Load
Postback and ViewStateNo request-reply cycle; state lives in the component, and Blazor applies a diff of the rendered output after each event
SessionNot available in server-side Blazor, because the connection is not tied to an HTTP request; the book says such an app “requires rearchitecting”
<asp:Button> with a server-side OnClick handler<button> with an @onclick handler
<asp:RequiredFieldValidator>EditForm with DataAnnotationsValidator and ValidationMessage
Master page (MasterPageFile)Layout component (@layout)
Global.asax, HTTP modules and handlersProgram.cs and middleware
Web.config and ConfigurationManagerappsettings.json and IConfiguration

The book focuses on server-side hosting because it “more closely resembles Web Forms”: the code runs on the server and a SignalR connection carries UI events. Blazor WebAssembly runs in the browser and, as the book notes, needs a separate service for databases and internal systems.

Third-party controls do not carry over. A Telerik or DevExpress grid in a Web Forms application is a server control; the vendors sell separate suites for Blazor (Telerik UI for Blazor ↗, DevExpress Blazor UI Components ↗), and each page that uses a grid, scheduler or editor is rebuilt against the new component and its own API. We did not find a converter from either vendor that turns Web Forms markup into Blazor.

Razor components compile only in C# projects. The book: “You can’t compile .razor files from a Visual Basic project.” Visual Basic class libraries can still be referenced from the Blazor project.

Option 4: third-party runtimes and converters

  • DotVVM ↗, open source under the Apache license and part of the .NET Foundation: an MVVM framework that “can run side-by-side with other ASP.NET frameworks (Web Forms, MVC, Razor Pages)” on .NET Framework 4.7.2 and later, so pages can be replaced one by one inside the existing application. Its guidance: “When all Web Forms pages are gone, switch to .NET 8+.”
  • CoreForms ↗ by RUBICON IT: a commercial runtime that “allows you to maintain and run your existing Web Forms code as a .NET Core application” by providing the System.Web namespace and the client-side resources to ASP.NET Core. It runs on Windows only (Kestrel, IIS, HTTP.sys) and is not available on Linux. Web Forms code and MVC or Razor Pages can share one application, so a later migration can go page by page. A trial package, CoreForms.Web, is on NuGet; its current version targets .NET 10.
  • GAP AI Migrator for Web Forms ↗, the tooling formerly sold as Mobilize.Net WebMAP (the old address redirects to GAP’s site): automated conversion of a Web Forms application “to modern web architectures with Blazor and ASP.NET Core”, where the UI becomes a Blazor front end and “backend code is converted to ASP.NET Core C#”.
  • WebFormsCore ↗: a public GitHub project that reimplements the Web Forms model (.aspx and .ascx files, controls, a [ViewState] attribute) for ASP.NET Core 10 or higher. Its readme says it “is heavily inspired by WebForms but is not a direct port. There are many breaking changes” and that it “is still in early development and is not ready for production use”.

How to size your own application

  • Count the .aspx and .ascx files and sort them by how often they change. Pages nobody touches can wait in the Framework application behind a proxy. Pages that change every sprint are the first to move.
  • List the third-party controls page by page. Each one is a page rebuilt against a Blazor component or plain HTML.
  • Find what relies on ViewState and Session. ViewState disappears with postbacks. Session has a path in the incremental migration (remote or wrapped session through the adapters) and none in server-side Blazor without a redesign.
  • List the HTTP modules and handlers in Web.config and the events in Global.asax. They become middleware, or stay as modules through the adapters during the transition.
  • Read Web.config for anything beyond connection strings: custom sections, URL rewrite rules, the authentication mode, configBuilders. Each goes somewhere else in ASP.NET Core.
  • Reporting: the Microsoft Report Viewer control is a Web Forms control, and its NuGet package Microsoft.ReportingServices.ReportViewerControl.WebForms targets .NET Framework only. Pages that embed it need another way to render reports.

Not sure which option fits your application?

Send us the list of projects in the solution, or a few sentences about the application, and we reply by email with what blocks the move and what we would propose. The check is free and commits you to nothing.

If you want us to do the work, we agree a fixed price for an agreed scope, by email.

  • What does the application do and who uses it?
  • Which .NET Framework version and project types (ASP.NET MVC, Web Forms, WCF, Windows service, WinForms/WPF)?
  • Which third-party packages or components does it depend on?
  • What is the goal: .NET 8/10 on Windows, Linux, containers, cloud?

A practical order

  1. Move class libraries to .NET Standard 2.0, or multi-target net48 and net8.0. Microsoft’s incremental guide asks for exactly this, in dependency order: leaf libraries first, the web project last. Where a library needs HttpContext, replace the System.Web reference with the Microsoft.AspNetCore.SystemWebAdapters package.
  2. Pull logic out of code-behind into those libraries. The Blazor book puts it as N-tier, where “the app model (in this case, Web Forms) is separate from the business logic. This logical separation of layers makes it clear what needs to move to .NET Core and Blazor.” This is where a Page_Load that queries the database directly gets fixed.
  3. Move the processes that have no UI: services, jobs, Web API. They compile against the same libraries and can go to .NET 8 or 10 on their own.
  4. Then the UI, by one of the routes above: page by page behind YARP, into DotVVM or CoreForms, or a Blazor rewrite.

Two Microsoft tools apply. .NET Upgrade Assistant, in Visual Studio and as a command-line tool, analyzes a project and its dependencies and upgrades project files; Microsoft marks it as deprecated and points to the GitHub Copilot upgrade agent. That agent, according to Microsoft, assesses the solution, writes an upgrade plan, carries it out with a Git commit per step, supports ASP.NET Web Forms projects from any .NET Framework version to .NET 8 or later, and lists a “WebForms-to-Blazor upgrade” scenario. We have not measured how much of a real Web Forms page either tool converts.

If you would rather hand the whole thing over, the migration service does the assessment and the work for a fixed price.

Sources

More guides