
Evincia
What breaks by .NET application type
Whether a modernization is a port or a rewrite is decided less by your .NET version than by what kind of application it is.
There are two axes to a .NET modernization, and teams usually scope along the wrong one. The first is the Framework version -- 3.5, 4.7.2, 4.8 -- which is what most planning fixates on because it has a number and a support date. The migration risk guide covers that axis.
The second axis is the application type -- what kind of program it is, not which version of the framework it runs on -- and it's the one that usually decides the cost. Two applications on the exact same .NET Framework 4.8 can be six months and three years of work, because one is an ASP.NET MVC API that ports to ASP.NET Core and the other is a Web Forms portal with no equivalent in modern .NET. The version is incidental. The application type tells you whether you are doing a port (recompile and fix), an upgrade (real work, but the program still exists), or a rewrite (rebuild from scratch).
This page is the field guide to that axis: for each kind of .NET application, what actually happens when you move it to modern .NET, and where the realistic path lands. The facts here are grounded in Microsoft's own porting documentation (linked at the end); the framing -- which of these tends to surprise teams, and why -- is field-observed.
Why application type, not version, drives the cost
Modern .NET (.NET 6, 8, 10) is a different runtime from .NET Framework, not a newer Framework. For some application types the move is a recompile-and-fix-warnings exercise; for others the underlying programming model simply doesn't exist on the new runtime, and "migration" means "rebuild." The Framework version sets the lifecycle clock. The application type sets the size of the job.
The most expensive mistake at the planning stage is estimating from the version. "We're on 4.8, and 4.8-to-.NET-8 is well documented" is true and beside the point if half the solution is Web Forms and server-side WCF. The honest estimate comes from inventorying the application types first -- which is what the triage checklist has you do -- and then reading the path for each below.
Port, upgrade, or rewrite -- the map
Every .NET application type falls into one of three buckets when moving to modern .NET. The bucket is the headline; the per-type sections below are the detail.
-
Ports cleanly -- recompile and fix
- Console & batch apps
- Class libraries / shared code
- ASP.NET MVC 5 & Web API 2
- WCF client code
- Windows Services → Worker Service
-
Upgrade -- Windows-only
- Windows Forms
- WPF
-
Rewrite -- no direct equivalent
- ASP.NET Web Forms
- Server-side WCF → CoreWCF or gRPC/REST
- ASMX, .NET Remoting, COM+, Workflow Foundation
- Port -- recompile and fix
- Upgrade -- Windows-only
- Rewrite -- no direct equivalent
Bars show relative effort, not estimates -- the lengths compare application types to each other; they are not a schedule, and the weeks / months / years marks are orders of magnitude. Grounded in Microsoft's porting guidance linked at the foot of the page. Color encodes the bucket: green = port, yellow = upgrade, red = rewrite.
Ports cleanly (recompile and fix; weeks to months)
- Class libraries and shared code -- retarget to
net10.0(the current LTS) ornetstandard2.0; the .NET Framework compatibility mode and the Windows Compatibility Pack cover most gaps. - Console and batch applications -- the app model exists unchanged; usually little more than a project-file conversion.
- ASP.NET MVC 5 and Web API 2 -- a new app model (ASP.NET Core), so months of work, but every concept has a documented equivalent.
- WCF client code -- consuming a service is supported through the
System.ServiceModelclient packages.
Upgrades, but Windows-only (the runtime exists; the OS lock stays)
- WinForms and WPF -- both run on modern .NET (since .NET Core 3.0), but remain Windows-only. An upgrade, not a rewrite, with caveats on third-party controls and Windows-only APIs.
Rewrites or no direct equivalent (the model is gone; rebuild)
- ASP.NET Web Forms -- does not exist in modern .NET. The biggest single rewrite trigger.
- Server-side WCF -- not built in; CoreWCF (a subset) or a rewrite to gRPC/REST.
- ASMX web services, .NET Remoting, COM+ (
System.EnterpriseServices), Windows Workflow Foundation -- all unsupported on modern .NET, each with a re-architecture rather than a port.
Web applications
- ASP.NET Web Forms -- rewrite. Web Forms has no equivalent in modern .NET: the page lifecycle, ViewState, and
<asp:>server controls (the mechanics that made those old pages work) are gone and aren't coming back. Moving it means choosing a new UI model (Blazor, Razor Pages, or ASP.NET Core MVC) and rebuilding the presentation layer, not porting it. This is the classic "we thought it was a version upgrade" surprise -- and the admin portal nobody mentioned is almost always Web Forms. - ASP.NET MVC 5 -- port. Maps to ASP.NET Core MVC. It's a new app model, so it's real work (controllers, filters, and routing carry over conceptually; configuration moves from
web.configto code, and dependency injection becomes mandatory), but it's months, not years, for a healthy codebase. - ASP.NET Web API 2 -- port. Maps to ASP.NET Core Web API, the cleanest of the web ports. The controller model is familiar; the work is in hosting, configuration, and the middleware pipeline.
- ASMX web services -- rewrite. The legacy SOAP web-service model (an early way for applications to talk to each other) isn't supported on modern .NET. Re-expose the functionality as an ASP.NET Core service (REST or gRPC), which is a re-implementation of the endpoint, not a recompile.
Two of these four are the cheap kind of move and two are the expensive kind, and they don't announce which is which from the outside -- a customer-facing site and an internal admin portal can look identical in a demo while one is a port and the other is a rewrite. That split is worth knowing before a number is committed.
Services and back-end
- WCF -- it depends on server vs client. WCF splits along a line teams most often miss. Client code that calls a WCF service is supported on modern .NET via the
System.ServiceModelclient packages -- a port. Server-side hosting is not built into modern .NET: you either adopt CoreWCF (a Microsoft-supported open-source port that brings a subset of WCF hosting to modern .NET, the right choice when existing clients must keep working) or rewrite to gRPC or REST (Microsoft's recommended direction for new RPC work). Server-side WCF with custom bindings or behaviors is where this gets expensive, and.svc-hosted services need the most hands-on conversion. - Windows Services -- port. Modern .NET hosts long-running background work (the unattended jobs that run on a server) as a Worker Service (a
BackgroundServicein the generic host), and it can still run as a Windows Service. The hosting model changes; the work the service does usually carries over directly. - Console and batch applications -- easy port. The console app model is unchanged on modern .NET. These are typically the lowest-risk projects in a solution and a good place to prove out the upgrade tooling before the hard parts.
The practical trap here is that "we use WCF" is one line in a status report but two very different bills depending on which side you host. Calling a service is cheap to carry forward; running one is the part that turns into a project, and it's the part nobody volunteers until someone asks.
Desktop applications
- Windows Forms -- upgrade, Windows-only. WinForms and WPF (the two long-standing ways of building Windows desktop applications) run on modern .NET and are actively maintained, but they stay Windows-only. The migration is an upgrade: the project file changes to the SDK format, some Windows-only APIs may need the
Microsoft.Windows.CompatibilityNuGet package, and the oldWebBrowsercontrol is replaced by WebView2. The real risk is third-party UI control suites (older Telerik, DevExpress, Infragistics builds) that may not have modern .NET versions. - WPF -- upgrade, Windows-only. Same story as WinForms: supported on modern .NET, Windows-only, an upgrade rather than a rewrite. Microsoft publishes migration guidance for both. The friction is again third-party controls and any Windows-specific API surface, not the UI framework itself.
Desktop is the bucket teams are most often pleasantly surprised by: the assumption is that an old WinForms or WPF app is a rewrite, and it usually isn't. The caveat that matters is the Windows-only constraint -- if part of the modernization goal was getting off Windows, desktop apps don't get you there.
Libraries, COM, and dead-end technologies
- Class libraries and shared code -- port. Retarget to
net10.0(ornetstandard2.0if the library must still serve Framework consumers during the transition). The .NET Framework compatibility mode lets modern projects reference some Framework libraries to unblock incremental migration, and the Windows Compatibility Pack restores around 20,000 APIs (Registry, WMI, EventLog, and more) when needed. - COM interop -- supported, Windows-only. Calling COM components (a decades-old Windows way of letting separate pieces of software talk) through interop works on modern .NET on Windows. What does not work is COM+ /
System.EnterpriseServices, which is unsupported -- serviced components have to be re-architected. - The dead-end technologies -- re-architecture, regardless of application type. Several .NET Framework technologies simply don't exist on modern .NET and can't be ported, only replaced: application domains (use processes, containers, or
AssemblyLoadContext), .NET Remoting (use gRPC, REST, or IPC), code access security and security transparency (use OS-level boundaries), and Windows Workflow Foundation (the community CoreWF, or a redesign). Finding one of these in a codebase changes the modernization from a migration into a partial redesign.
Most shared code travels to modern .NET with little drama, but a handful of older building blocks have no successor at all -- they have to be rebuilt a different way. The cost difference between "we ported it" and "we discovered a dead-end dependency" is large, and it hides in the kind of foundational code nobody has touched in years.
Mixed estates, and why not everything is a rewrite
Real solutions are rarely one application type. A typical mid-market .NET solution is a Web Forms admin portal, an MVC customer site, a couple of WCF services, a Windows Service that runs overnight, a pile of shared class libraries, and one COM dependency from 2011. Each has its own path, and the important rule is that a mixed estate is gated by its hardest component. One Web Forms portal or one Remoting channel sets the rewrite timeline for everything that depends on it.
The flip side is the part that gets lost in modernization anxiety: most application types are not rewrites. Console apps, libraries, MVC, Web API, Windows Services, and even WinForms and WPF are ports or upgrades. The rewrites are a specific, identifiable list -- Web Forms, server-side WCF, ASMX, Remoting, COM+, Workflow Foundation -- and the value of inventorying by application type is that it separates the genuinely hard parts from the parts that just feel old. A modernization plan that treats the whole estate as a rewrite is as wrong as one that treats it all as a recompile.
How this fits the rest of the picture
Application type is one of the inputs to Architectural Coupling in the Modernization Readiness methodology, alongside how the pieces depend on each other. Read this page with the migration risk guide (the version axis) and the triage checklist (which has you inventory the application types in the first place). Where the database is doing the work, the SQL Server modernization risk guide covers the other half of the system.
That inventory -- which application types you have, and which bucket each falls in -- is what Modernization Shield produces from the actual code: the engine reads the .NET solution and maps the application types, dependencies, and coupling, and the result is a written picture of which parts are ports, which are upgrades, and which are rewrites, sized for a decision rather than a guess.
Port or rewrite? The application types decide.
Modernization Shield identifies Web Forms, System.Web, WCF, desktop, COM, package, and runtime dependencies across the solution. It separates applications that can be upgraded from those that need replacement or a different migration path before the estimate becomes a budget.
The SocialGoal sample Modernization Risk Report shows how those application-type findings are evidenced and turned into a sequence of work.
About this page
Last updated: .
The technical facts on this page -- what is and isn't supported on modern .NET -- are grounded in Microsoft's porting documentation: the overview of porting from .NET Framework to .NET ↗, the list of .NET Framework technologies unavailable on .NET ↗, and Microsoft's WCF-to-gRPC/CoreWCF migration guidance ↗. The framing of what tends to surprise teams is field-observed. Microsoft's support details change; verify the specifics for your target. If a claim here contradicts your direct experience, email info@evincia.co.
Companion pages: the .NET Framework migration risk guide for the version axis, the triage checklist for the full inventory, the SQL Server modernization risk guide for the database half, and the methodology for how the dimensions are scored.
