← Back to blog

WebForms Migration: Blazor, Razor Pages or React?

ASP.NET WebForms has no direct successor in modern .NET. How to choose between Blazor, Razor Pages and React, and how to migrate without a big-bang rewrite.

You cannot upgrade ASP.NET Web Forms to ASP.NET Core in place. Web Forms was never ported to .NET Core or modern .NET, so moving to .NET 10 means rebuilding the UI in Blazor, Razor Pages, MVC or a JavaScript front end such as React. Pick the target by team skills and how interactive your screens are, then migrate one page at a time behind a YARP proxy instead of attempting a big-bang rewrite.

Can Web Forms run on .NET 10?

No. Microsoft’s guide Blazor for ASP.NET Web Forms developers explains that the .NET team decided against porting Web Forms to .NET Core because the breaking changes required were too drastic. Web Forms stays a Windows-only part of .NET Framework 4.8.x.

That does not make it unsupported today. Microsoft’s position is that Web Forms remains supported for as long as .NET Framework ships with Windows. The pressure to move usually comes from hosting, hiring, security reviews and the rising cost of every change.

Microsoft now ships tooling for the move. Its documentation for the GitHub Copilot upgrade agent, updated in September 2026, lists a WebForms-to-Blazor scenario that converts pages, controls and code-behind into Blazor Server components. I look at what that tooling does well and where it needs a human in my review of Copilot app modernization for .NET.

What happens to ViewState, postbacks and UpdatePanels?

The C# in your code-behind usually ports with modest changes. The page model is what has to be rethought. This table shows where each Web Forms feature lands in the three main targets.

Web Forms featureBlazorRazor Pages / MVCReact + ASP.NET Core API
ViewStateComponent state in memory, on the server circuit or in the browserNo equivalent. Reload data per request or use hidden fieldsClient-side state in components
Postbacks and server events (Button_Click)@onclick handlers. The closest matchForm POST to a page handler or controller actionAPI calls from the browser
UpdatePanel partial refreshBuilt in. Components re-render only what changedA small script, or a Blazor component embedded in the pageNormal SPA behaviour
User controls (.ascx)Razor componentsPartial views, view components, tag helpersReact components
Server controls (GridView, Repeater)Component libraries or hand-built tablesTag helpers and plain HTMLComponent libraries
Code-behind and the page lifecycle@code block or a .razor.cs partial classPageModel class or controllerSplit between components and API controllers
Master pagesLayouts_Layout.cshtmlLayout components

ViewState deserves a specific warning. Web Forms pages often keep lookups, selected rows and even business data in ViewState between postbacks. Blazor Server keeps equivalent state in a server-side circuit for each browser tab. That feels familiar, but it costs server memory, and the state is lost if the connection stays down too long. Razor Pages has no page state at all, so each request rebuilds what it needs. Find out what your pages keep in ViewState before you choose.

Session is the other trap. Microsoft’s Copilot upgrade documentation includes a skill dedicated to Blazor Server problems such as a null Session inside WebSocket circuits and lost wizard or cart state. Expect to redesign anything that leans heavily on Session.

Should you use Blazor Server, Blazor WebAssembly or static rendering?

Since .NET 8, Blazor is chosen per component through render modes. Static server rendering produces plain HTML with no interactivity. Interactive Server runs components on the server over a SignalR connection. Interactive WebAssembly runs them in the browser. Interactive Auto starts on the server and switches to WebAssembly once the bundle has downloaded.

Microsoft lists four Blazor Server limitations. Every user interaction is a network hop, there is no offline support, scaling to many users needs server resources for each connection, and you need an ASP.NET Core server to host it. Blazor WebAssembly reverses those trade-offs with a larger download, code that users can inspect, and the option of hosting the whole app as static files.

For an internal line-of-business app on a reliable network, Interactive Server is the closest match to how Web Forms developers already think. It is also the target of Microsoft’s Copilot WebForms scenario.

When are Razor Pages or MVC the better choice?

Razor Pages is a page-based, server-rendered model. Each page has its own handler class, and the HTML arrives ready to display. For Web Forms apps that are mostly forms, lists and reports, it is often the simplest target. It needs no persistent connection, scales like any web app and gives search engines complete HTML.

Choose MVC when the app already mixes pages with Web API endpoints, or when your developers know MVC well. In both cases you can drop an interactive Blazor component into a page where one screen needs rich behaviour. Microsoft designed MVC, Razor Pages and Blazor to be used together.

When does React make sense for a Web Forms migration?

React with an ASP.NET Core API fits when you already employ front-end developers, the UI is highly interactive, or the same API will serve a mobile app or partners. Microsoft’s own comparison names the downsides: more languages, frameworks and tools, and logic that is hard to share between client and server. For a C# team rescuing a Web Forms app, that can mean running two migrations at once.

If public pages need to rank in search, plan server-side rendering from the start, for example with Next.js. A client-only React app serves an empty shell until its JavaScript runs.

How do you choose between Blazor, Razor Pages and React?

FactorBlazor ServerBlazor WebAssemblyRazor Pages / MVCReact + API
Team skillsC# onlyC# onlyC# and HTMLC# plus TypeScript and React
UI complexityRich, stateful screensRich screens, offline possibleForms, lists, reportsRich, client-heavy apps
InteractivityHigh, via server round tripsHigh, in the browserLow to mediumHigh, in the browser
SEOGood with prerendering, which is on by defaultWeak unless a server prerendersStrong, full HTMLNeeds a server-rendering framework
HostingASP.NET Core server holding a connection per tab; Azure SignalR Service at scaleStatic files or a CDN when standaloneAny ASP.NET Core hostStatic front end plus an API host
Distance from Web FormsClosestCloseModerateFurthest

You can mix them. A sensible outcome for many line-of-business apps is Razor Pages for public and simple pages, with Blazor components for the few screens that need rich interaction.

How do you migrate Web Forms without a big-bang rewrite?

For large production apps, Microsoft recommends incremental migration, which its documentation describes as an implementation of the strangler fig pattern. A new ASP.NET Core app sits in front of the old one and forwards every request it cannot handle yet to the Web Forms app, using YARP, Microsoft’s reverse proxy library. Pages move across one at a time. Users see a single site throughout.

  1. Stand up the proxy. Create the ASP.NET Core app with YARP forwarding all traffic to the existing site, and put it into production before you migrate anything.
  2. Share authentication and session. The System.Web adapters let the new app defer authentication to the old one and share session state, so users stay signed in as they move between old and new pages.
  3. Upgrade shared libraries in order. Move class libraries to .NET Standard 2.0, or multi-target them, starting with those that depend on nothing else. Swapping the System.Web reference for the Microsoft.AspNetCore.SystemWebAdapters package keeps code that uses HttpContext compiling.
  4. Pin down each page before moving it. Record what the page does today with characterisation tests: inputs, outputs, database changes and emails sent.
  5. Move a page, switch the route, repeat. When the new page passes the recorded tests, route it to ASP.NET Core. Rolling back is a routing change.
  6. Retire the old app when nothing routes to it any more.

Take a hypothetical 120,000-line Web Forms app with 150 pages. A big-bang rewrite freezes features for months and goes live in one risky weekend. The strangler approach lets the team ship the ten most-used pages first, learn from them, and keep fixing the remaining old pages until their turn comes.

Where does AI help in a Web Forms migration?

AI agents are good at the mechanical part, such as turning a GridView and its code-behind into a component or an event handler into a page handler. They cannot know which ViewState quirk a user relies on. That is why I pair agents with recorded behaviour and review every change before it merges.

The Modernisation Blueprint applies this to one real page of your application in two weeks as a fixed-price package from £20,000. You get the migrated page with passing characterisation tests, a target architecture and a fixed price for the rest.

Choose the target page by page if you need to, but choose the migration method once: a proxy in front, tests before each move, and the old app retired only when nothing routes to it.

Sources

Frequently asked questions

Is ASP.NET Web Forms still supported?

Yes, as part of .NET Framework 4.8.x. Microsoft says Web Forms remains supported as long as .NET Framework ships with Windows. It is feature-frozen and Windows-only, and Microsoft has said it will not be ported to ASP.NET Core. Apps that need modern .NET, Linux containers or current tooling have to be rebuilt in Blazor, Razor Pages, MVC or a JavaScript front end.

Can I upgrade a Web Forms app to .NET 10 directly?

No. Web Forms is not part of ASP.NET Core, so no project setting moves a Web Forms app to .NET 10. Class libraries and business logic can often be upgraded, and Microsoft's GitHub Copilot upgrade agent can convert pages to Blazor Server components. Each page still has to be rebuilt in the new UI framework and tested against the behaviour of the old one.

Is Blazor the replacement for Web Forms?

It is the closest match. Microsoft describes Blazor as a natural solution for Web Forms developers because both use stateful, event-driven components written in C#, and Blazor Server feels most like Web Forms. Razor Pages is often the better choice for form-and-report apps and public pages, and React suits teams that already have front-end developers.

What replaces ViewState in Blazor or Razor Pages?

Nothing directly. Blazor Server keeps component state in memory in a server-side circuit for each browser tab, and Blazor WebAssembly keeps it in the browser. Razor Pages and MVC keep no page state, so each request reloads what it needs from the database or a cache. Audit what each Web Forms page stores in ViewState before choosing a target, because large ViewState usually signals state you must redesign.

Can we migrate a Web Forms app one page at a time?

Yes. Microsoft recommends incremental migration for large apps. A new ASP.NET Core app sits in front of the Web Forms site and uses the YARP reverse proxy to forward any request it cannot handle yet. The System.Web adapters share authentication and session between the two apps. You move pages across one by one and retire the old app when no routes point to it.

Not sure which target fits your Web Forms app?

We choose the target for your pages and rewrite them in slices, as a fixed-price package with tests that prove behaviour is unchanged.

See the modernisation packages