Skip to content

Migration guide

WebForms & .NET Framework → .NET 10 Checklist

A step-by-step checklist for modernizing legacy .NET — inventory, target selection, honest tooling, bottom-up sequencing, parity testing, EF6 to EF Core, and cutover.

Last updated Jul 26, 2026

dotnet-modernization

.NET Framework 4.8 still runs — but everything around it is moving on: the free migration tooling is retired, .NET 8 and 9 leave support on November 10, 2026, and every year on WebForms shrinks your hiring pool. This is the checklist we run in client modernization engagements. Work it top to bottom; every unchecked box is schedule risk.

1. Inventory the solution

Migrations fail on surprises, and surprises live in the inventory you didn’t take:

  • List every project with its target framework, and map the dependency graph between them — the graph, not the folder structure, dictates migration order.
  • Audit NuGet packages: which have .NET 10-compatible versions, which have successors, which are abandoned. Abandoned packages with no successor are your first blockers.
  • Measure the WCF surface: services, bindings, security modes, and which clients call them. Message-layer security and exotic bindings need special handling.
  • Count WebForms pages and controls — especially third-party suites (Telerik, DevExpress, Infragistics) and custom server controls, which have no automatic translation.
  • Be honest about test coverage. If behavior isn’t pinned by tests today, parity verification (step 5) becomes the migration’s biggest work item.
  • Map integration seams: file drops, MSMQ, scheduled tasks, COM interop, registry reads — the things that only surface in production.

2. Pick your targets

  • Runtime: .NET 10 LTS (supported to November 2028). Don’t target 8 or 9 — both leave support on November 10, 2026, and you’d be migrating twice.
  • Web UI: decide per-app between Blazor (C#-first teams, forms-heavy screens), API-first with the existing UI strangled gradually, or a SPA rewrite if you already own frontend capacity.
  • Data: EF6 → EF Core (see step 6), or Dapper where the EF surface was thin anyway.
  • WCF: CoreWCF for compatible contracts you want moved cheaply; gRPC or REST for services that deserved a redesign anyway.

3. Be honest about tooling

The free, deterministic .NET Upgrade Assistant was deprecated in late 2025 — it still hides behind a disabled-by-default setting in Visual Studio 2026, but it’s frozen. Its successor, GitHub Copilot app modernization, requires a paid Copilot plan and is non-deterministic: useful for the mechanical share, unreliable on large, undocumented, or unconventional codebases.

Plan accordingly:

  • Treat AI output as a draft, not a result: every change goes through a build gate, a test gate, and human review.
  • Budget for the last mile. Package swaps and namespace changes are the easy 70%; verifying business behavior, untangling undocumented patterns, and deciding what to redesign is the project.
  • Keep migrations replayable: script what can be scripted so a failed attempt costs hours, not the branch.

Doing this under a deadline? We run this checklist as a fixed-scope Modernization Readiness Assessment — inventory, blockers, parity strategy, and a sprint-level plan, from $4,800.

4. Sequence bottom-up

  • Start with leaf class libraries: move them to .NET Standard 2.0 or multi-target (net48;net10.0) so old and new worlds share code during the transition.
  • Break circular dependencies first — they block multi-targeting and they were a design smell on .NET Framework too.
  • Migrate services and background jobs before UIs; they have the clearest contracts to verify.
  • Use a strangler-fig on the web surface: route converted sections to the new app, keep the rest on WebForms, retire pages incrementally. Shipping value mid-migration is what keeps the program funded.

5. Build the parity harness

The migration’s real deliverable isn’t compiling code — it’s identical behavior:

  • Golden-master tests: capture current outputs (reports, invoices, exports, API responses) as fixtures and diff the migrated system against them.
  • Request/response capture: record real production traffic shapes and replay them against the new stack.
  • Watch the quiet killers: culture and encoding defaults, date/decimal rounding, sort stability — categories where .NET Framework and modern .NET disagree without throwing.
  • Run old and new side by side on the same inputs wherever the architecture allows; a diff report beats a code review for behavioral confidence.

6. Migrate the data layer

EF6 → EF Core is a behavior change, not a package swap:

  • Query translation differs — expressions that ran in memory under EF6 may translate to SQL (or throw) under EF Core, and vice versa. Re-verify every non-trivial query.
  • Lazy loading is opt-in and proxied differently; navigation-property access patterns that silently worked may now return null or N+1.
  • Cascade delete configuration and transaction behavior deserve an audit — the defaults are closer than folklore suggests, but anything relying on SaveChanges ordering or implicit transaction scope needs verification.
  • Verify GroupBy and date arithmetic against production-shape data volumes, not seed data — translation quality decisions only show up at scale.

7. Cut over and right-size the infrastructure

  • Hosting changes shape: IIS app pools become Kestrel behind a reverse proxy or containers; web.config becomes appsettings + environment; and both machineKey material (now ASP.NET Core Data Protection) and session state (now session middleware over a distributed cache) need explicit replacements.
  • Wire observability before cutover — you want baseline metrics from the old system to compare against, not just green checks on the new one.
  • Modern .NET runs anywhere, so re-quote your infrastructure: client migrations we’ve run land at 60–90% cost reductions, and our own template re-platform did better still — 94%, with 92% faster compute. Where you land depends on how much of the old bill was managed-service premium.
  • Decommission on a date. A frozen .NET Framework deployment kept “just in case” is unpatched attack surface with a licensing bill.

Last updated July 2026 — verified against .NET 10 LTS and current Visual Studio 2026 tooling. Rather hand this list to someone who has run it before? Book an $80 session — it counts toward the assessment.

Frequently asked questions

Can we still run .NET Framework 4.8 in production?

Yes — 4.8 ships with Windows and keeps receiving security patches, so it isn't end-of-life the way IdentityServer4 or .NET Core 3.1 are. The pressure comes from everything around it: no new features, Windows-only hosting, a shrinking hiring pool for WebForms, and third-party packages that stopped targeting Framework years ago. You can run it; you just pay a growing tax for every year you do.

What replaced the .NET Upgrade Assistant?

Microsoft deprecated the free .NET Upgrade Assistant in late 2025. Its replacement is GitHub Copilot app modernization — an AI agent in Visual Studio that requires a paid Copilot plan (Pro, Business, or Enterprise). The old tool still exists behind a disabled-by-default setting in Visual Studio 2026 but is no longer developed. Practically: plan for AI-assisted-but-human-verified migration work, not a free push-button upgrade.

Should WebForms go to Blazor or something else?

Blazor is the natural target when your team is C#-first and the app is forms-and-tables heavy — the component model maps well and server-side Blazor keeps the programming feel familiar. An API-first split (modern backend now, UI decision later) is often smarter when the risk lives in the business logic rather than the UI. A JavaScript SPA rewrite only pays if you already have frontend capacity. The wrong answer is rewriting everything at once.

How long does a .NET Framework to .NET 10 migration take?

Class libraries and services usually move in weeks; WebForms UIs and heavily customized data layers set the real timeline. A small internal app is a weeks-scale project; a mid-size line-of-business system is typically several months — but sequenced correctly (libraries first, strangler-fig on the web surface) you ship working increments the whole way instead of gambling on a big bang.

Is .NET 8 still safe to stay on?

For now — but .NET 8 and .NET 9 both reach end of support on November 10, 2026, after which neither receives security patches. .NET 10 is the current LTS, supported to November 2028. The 8-to-10 jump is far smaller than leaving .NET Framework, so schedule it as routine maintenance this year rather than emergency work next year.

Deep dives in this cluster

4 posts sharing this guide's themes.