FreedomDev
TeamAssessmentThe Systems Edge616-737-6350
FreedomDev Logo

Your Dedicated Dev Partner. Zero Hiring Risk. No Agency Contracts.

201 W Washington Ave, Ste. 210

Zeeland MI

616-737-6350

[email protected]

FacebookLinkedIn

Company

  • About Us
  • Culture
  • Our Team
  • Careers
  • Portfolio
  • Technologies
  • Contact

Core Services

  • All Services
  • Custom Software Development
  • Systems Integration
  • SQL Consulting
  • Database Services
  • Software Migrations
  • Performance Optimization

Specialized

  • QuickBooks Integration
  • ERP Development
  • Mobile App Development
  • Business Intelligence / Power BI
  • Business Consulting
  • AI Chatbots

Resources

  • Assessment
  • Blog
  • Resources
  • Testimonials
  • FAQ
  • The Systems Edge ↗

Solutions

  • Data Migration
  • Legacy Modernization
  • API Integration
  • Cloud Migration
  • Workflow Automation
  • Inventory Management
  • CRM Integration
  • Customer Portals
  • Reporting Dashboards
  • View All Solutions

Industries

  • Manufacturing
  • Automotive Manufacturing
  • Food Manufacturing
  • Healthcare
  • Logistics & Distribution
  • Construction
  • Financial Services
  • Retail & E-Commerce
  • View All Industries

Technologies

  • React
  • Node.js
  • .NET / C#
  • TypeScript
  • Python
  • SQL Server
  • PostgreSQL
  • Power BI
  • View All Technologies

Case Studies

  • Innotec ERP Migration
  • Great Lakes Fleet
  • Lakeshore QuickBooks
  • West MI Warehouse
  • View All Case Studies

Locations

  • Michigan
  • Ohio
  • Indiana
  • Illinois
  • View All Locations

Affiliations

  • FreedomDev is an InnoGroup Company
  • Located in the historic Colonial Clock Building
  • Proudly serving Innotec Corp. globally

Certifications

Proud member of the Michigan West Coast Chamber of Commerce

Gov. Contractor Codes

NAICS: 541511 (Custom Computer Programming)CAGE CODE: oYVQ9UEI: QS1AEB2PGF73
Download Capabilities Statement

© 2026 FreedomDev Sensible Software. All rights reserved.

HTML SitemapPrivacy & Cookies PolicyPortal
  1. Home
  2. /
  3. Solutions
  4. /
  5. .NET Framework to .NET 8 Migration: The Strangler Pattern That Actually Works
Solution

.NET Framework to .NET 8 Migration: The Strangler Pattern That Actually Works

Your .NET Framework 4.x monolith still works — but it is Windows-only, IIS-bound, locked out of C# 12, and maintained by a shrinking developer pool. FreedomDev migrates legacy .NET Framework applications to .NET 8 using the strangler fig pattern: module-by-module extraction behind YARP reverse proxy, zero downtime, zero feature freeze. WCF to gRPC, EF6 to EF Core, ASP.NET MVC to Razor Pages or Blazor — we handle the breaking changes that the .NET Upgrade Assistant flags but cannot fix. Zeeland, MI. 20+ years of .NET migrations across manufacturing, healthcare, financial services, and logistics.

FD
20+ Years .NET Migration Experience
.NET Framework 1.1 Through .NET 8
Strangler Pattern Specialists
Zeeland, MI

.NET Framework 4.8 Is in Maintenance Mode: What That Means for Your Application

Microsoft ended active development on .NET Framework at version 4.8.1. There will be no 4.9. There will be no new language features, no performance improvements, no new APIs, and no updates to the BCL beyond security patches. .NET Framework 4.8.1 is the terminal release. Microsoft's official guidance since 2019 has been unambiguous: all new development should target .NET (formerly .NET Core), and existing .NET Framework applications should plan migration. The framework will continue to receive security patches because it ships as a Windows component, but it is functionally frozen. Every month you stay on .NET Framework, the gap between your application and the current platform widens — and it is not a gap that shrinks on its own.

The technical debt compounds in specific, measurable ways. Your application is locked to Windows Server and IIS. That means Windows Server licensing at $1,000-6,000 per server per year depending on your edition and core count, plus IIS management overhead that disappears entirely when you deploy to Linux containers on a $20/month VPS or a managed Kubernetes cluster. Your developers cannot use C# 12 features — primary constructors, collection expressions, inline arrays, interceptors — because the Roslyn compiler targets .NET Framework 4.8 with C# 7.3 as the maximum supported version. Your NuGet package ecosystem is eroding: major libraries have stopped publishing .NET Framework-compatible versions. Newtonsoft.Json still works, but the ecosystem is consolidating around System.Text.Json with source generation. Polly v8 dropped .NET Framework support. MediatR 12+ requires .NET 6 minimum. Every library update your team evaluates now starts with the question: does this even support our framework version?

Performance is where the gap becomes undeniable. .NET 8 delivers 3-10x throughput improvements over .NET Framework 4.8 depending on the workload profile. Microsoft's own TechEmpower benchmark results show ASP.NET Core on .NET 8 handling over 7 million plaintext requests per second on standard hardware — a number that would require a rack of IIS servers to approach on .NET Framework. The improvements come from everywhere: Kestrel versus IIS pipeline overhead, Span<T> and Memory<T> reducing heap allocations, tiered JIT compilation with dynamic PGO recompiling hot paths at runtime, regions-based garbage collection cutting GC pause times, native AOT compilation for serverless cold starts measured in milliseconds instead of seconds, and System.Text.Json with source-generated serializers eliminating reflection entirely. Teams that have completed the migration consistently report 30-50% reductions in cloud compute costs from running the same business logic on fewer, smaller instances.

The talent problem is already real and it accelerates every year. The median .NET developer in 2026 has built their career on .NET Core and .NET 5+. They use Rider or VS Code, they deploy to Linux containers, they write Minimal APIs and use dependency injection that ships with the framework. When you post a job requiring .NET Framework 4.x, Web Forms, WCF, or classic MVC 5, you are filtering out the majority of the modern .NET developer market. The candidates who remain are either expensive specialists charging premium rates, or senior developers who would rather work on a modern stack and will leave as soon as they can. Your retention risk is directly tied to your framework version. Every year on .NET Framework narrows the hiring funnel and increases the cost of the developers willing to work in it.

Locked to Windows Server and IIS — $1,000-$6,000/server/year in licensing that disappears with Linux container deployment

C# 7.3 maximum language version — your developers cannot use primary constructors, pattern matching enhancements, collection expressions, or any feature from the last 7 years of C# evolution

NuGet ecosystem erosion — Polly v8, MediatR 12+, and increasingly more libraries have dropped .NET Framework support entirely

3-10x performance gap versus .NET 8 — paying for 3-5x more compute infrastructure to serve the same traffic

Shrinking developer talent pool — modern .NET developers build for .NET 8 on Linux, and your Framework 4.x job posting filters them out

.NET Framework 4.8.1 is the terminal release — no new features, no performance work, security patches only because it ships with Windows

Need Help Implementing This Solution?

Our engineers have built this exact solution for other businesses. Let's discuss your requirements.

  • Proven implementation methodology
  • Experienced team — no learning on your dime
  • Clear timeline and transparent pricing

Migration ROI: What Teams Measure After Moving to .NET 8

3-10x
Request throughput improvement over .NET Framework 4.8
30-50%
Cloud compute cost reduction from running on fewer, smaller Linux instances
$0
Windows Server licensing eliminated per migrated application
C# 12
Full access to modern language features, NuGet ecosystem, and tooling
Zero
Downtime during migration — strangler fig runs both versions concurrently
3-5x
Larger candidate pool when hiring developers for .NET 8 vs .NET Framework

Facing this exact problem?

We can map out a transition plan tailored to your workflows.

The Transformation

The Strangler Fig Migration: Module-by-Module Extraction With Zero Downtime

The strangler fig pattern is the only migration approach that consistently works for production .NET Framework applications with real users, real traffic, and zero tolerance for downtime. Named after strangler fig trees that grow around a host tree and gradually replace it, the pattern works by placing a reverse proxy in front of your existing .NET Framework application and routing traffic to new .NET 8 implementations as each module is migrated. The legacy application keeps running in production. Users never see a maintenance window. New modules go live one at a time. Old modules get decommissioned after the replacement is validated. At no point does anyone bet the business on a big-bang cutover.

FreedomDev implements this using YARP — Yet Another Reverse Proxy — Microsoft's own high-performance reverse proxy library built specifically for .NET. YARP sits in front of both your legacy IIS-hosted .NET Framework application and the new .NET 8 services. Route configuration determines which URLs go where: /api/orders might route to the new .NET 8 OrderService while /api/legacy-reports still routes to the .NET Framework monolith. As each module is migrated, tested, and validated in production, the YARP configuration updates to route its traffic to the new implementation. The legacy surface area shrinks with every sprint until nothing routes to the old application and it can be shut down. This is not theory — it is the approach Microsoft recommends in their official migration documentation, and it is how we have executed every .NET Framework migration since 2020.

The migration sequence matters. Not every module should be migrated in the order it appears in your solution explorer. We prioritize based on three factors: business value (which modules are blocking new feature development), technical risk (which modules have the most Windows-specific dependencies that need alternatives), and dependency graph position (which modules can be extracted cleanly versus which ones are deeply entangled with shared state). Typically, the healthiest migration order is: shared libraries and data access first (because everything depends on them), then API endpoints and background services (because they have well-defined boundaries), then UI layers last (because ASP.NET MVC views and Razor Pages require the most rewrite work). We have seen teams try to migrate the UI first and get stuck for months — the controllers depend on everything, and you cannot extract them without extracting their dependencies.

Microsoft's .NET Upgrade Assistant is a useful starting point but it is not a migration tool. It is a diagnostic tool that identifies breaking changes, generates a compatibility report, and automates some mechanical transformations — updating project file formats from .csproj with packages.config to SDK-style .csproj with PackageReference, converting web.config settings to appsettings.json, and flagging API calls that do not exist in .NET 8. What it cannot do is the actual engineering: redesigning WCF service contracts as gRPC proto definitions, replacing System.Web.HttpContext with ASP.NET Core's HttpContext abstraction, converting EF6 data models to EF Core with correct navigation property configuration, or refactoring code that depends on Global.asax application lifecycle events into the ASP.NET Core middleware pipeline. The Upgrade Assistant tells you what is broken. FreedomDev fixes it.

YARP Reverse Proxy: Side-by-Side Routing

YARP (Yet Another Reverse Proxy) is Microsoft's production-grade reverse proxy built on .NET. We deploy YARP as the front door to your application, routing each URL path to either the legacy .NET Framework backend or the new .NET 8 service. Route configuration is declarative — JSON or code-based — and can be updated at runtime without restarting the proxy. Health checks on both backends ensure that if a new service has issues, traffic automatically falls back to the legacy implementation. Session affinity, load balancing, and header-based routing are all built in. YARP handles the incremental cutover that makes strangler fig migration safe for production systems with real users.

WCF to gRPC Migration

Windows Communication Foundation is the single largest migration obstacle for most .NET Framework applications. WCF does not exist in .NET 8 — Microsoft explicitly chose not to port it. CoreWCF, the community-supported partial port, covers basic HTTP and NetTCP bindings but does not support WS-* specifications, message queuing, or the full range of WCF behaviors and extensions your application likely depends on. Our migration path is WCF to gRPC for internal service-to-service communication (binary Protocol Buffers, HTTP/2 multiplexing, bidirectional streaming, code-generated strongly-typed clients) and WCF to REST for public-facing endpoints where consumer compatibility matters. We convert DataContract and ServiceContract definitions to .proto files, rebuild service implementations using the Grpc.AspNetCore server package, and generate typed clients that replace your existing ChannelFactory<T> and proxy class usage.

Entity Framework 6 to Entity Framework Core

EF6 to EF Core is not a drop-in replacement. The two frameworks share a name and a general philosophy but differ in meaningful ways that affect application behavior. Lazy loading is opt-in rather than default in EF Core — code that relied on transparent lazy loading will throw null reference exceptions until navigation properties are explicitly included or lazy loading proxies are configured. The LINQ-to-SQL translation engine is completely different, and queries that worked in EF6 may translate to different SQL or fail to translate entirely in EF Core. GroupBy translation was incomplete until EF Core 7. Complex type mapping, table-per-hierarchy configuration, and many-to-many relationship conventions all changed. We migrate the data layer by running both EF6 and EF Core against the same database during the transition period, validating query output parity, and converting the model configuration from fluent API calls that use EF6 syntax to EF Core equivalents — including migration history so that EF Core's migration tooling can manage the schema going forward.

ASP.NET MVC 5 to ASP.NET Core

ASP.NET MVC 5 runs on System.Web, the IIS-coupled HTTP pipeline that does not exist in .NET 8. The migration replaces System.Web.Mvc with Microsoft.AspNetCore.Mvc, converts Global.asax application events to middleware components in the ASP.NET Core request pipeline, migrates Razor views from the legacy view engine to the ASP.NET Core Razor engine (which has a different tag helper syntax and different model binding behavior), replaces OWIN middleware with ASP.NET Core middleware, and converts authentication from FormsAuthentication or OWIN cookie authentication to ASP.NET Core Identity or the JWT bearer handler. Bundling and minification move from System.Web.Optimization to a build-time pipeline using Vite, webpack, or LibMan. Route configuration moves from RouteConfig.cs and attribute routing with System.Web.Mvc attributes to ASP.NET Core endpoint routing. If your application uses Web Forms pages mixed with MVC controllers — a common pattern in applications that were partially modernized from Web Forms to MVC — we handle that co-existence during the transition.

Windows Services to BackgroundService

Legacy .NET Framework Windows Services that handle background processing — file watchers, queue consumers, scheduled batch jobs, integration polling — migrate to the .NET 8 BackgroundService base class running as hosted services inside the ASP.NET Core host. This eliminates the separate Windows Service project, the sc.exe installation step, and the Windows-only dependency. BackgroundService implementations run on Linux, deploy as containers, and integrate with the same dependency injection, configuration, and logging infrastructure as your web endpoints. For scheduled jobs, we replace Windows Task Scheduler triggers with Hangfire or Quartz.NET running inside the application host, which gives you a dashboard, retry logic, and job history that Windows Task Scheduler never provided. For critical processing that needs supervision, we configure systemd units on Linux or Kubernetes liveness probes to ensure automatic restart on failure.

NuGet Package Compatibility Audit

Before migration begins, we audit every NuGet package in your solution against .NET 8 compatibility. Packages fall into four categories: fully compatible (published with .NET 8 target or .NET Standard 2.0), compatible with warnings (uses APIs that trigger platform compatibility analyzers), incompatible with replacement (the package dropped .NET Framework and you need to switch to the new version or an alternative), and incompatible with no replacement (niche packages that target .NET Framework-only APIs and require custom code to replace). Common replacements we handle: Microsoft.AspNet.WebApi.Client replaced by System.Net.Http.Json, Microsoft.Owin replaced by ASP.NET Core middleware, EntityFramework 6.x replaced by Microsoft.EntityFrameworkCore, System.Web.Mvc replaced by Microsoft.AspNetCore.Mvc, and dozens of packages that published breaking major versions that changed APIs alongside their .NET 8 support.

Want a Custom Implementation Plan?

We'll map your requirements to a concrete plan with phases, milestones, and a realistic budget.

  • Detailed scope document you can share with stakeholders
  • Phased approach — start small, scale as you see results
  • No surprises — fixed-price or transparent hourly
“
We had a 600K-line .NET Framework 4.6 monolith that seven developers maintained full-time. FreedomDev migrated it to .NET 8 over five months using the strangler pattern. We never had a minute of downtime. Our Azure bill dropped 40% from switching to Linux containers, and we shipped more features in the first quarter after migration than we had in the previous year on Framework.
VP of Engineering—Midwest Manufacturing Software Company

Our Process

01

Migration Assessment and Compatibility Report (1-2 Weeks)

We run the .NET Upgrade Assistant and ApiPort analyzer against your entire solution to generate a machine-readable compatibility report: which APIs have direct .NET 8 equivalents, which APIs have behavioral changes, and which APIs have no equivalent and require architectural decisions. We audit every NuGet package for .NET 8 compatibility. We map the dependency graph between projects in your solution to identify which modules can be extracted independently and which are tightly coupled. We document every WCF service contract, every Entity Framework 6 model, every Windows-specific API call, every System.Web dependency, and every COM interop reference. The deliverable is a migration plan with a prioritized module sequence, estimated effort per module, identified blockers that require architectural decisions, and a YARP routing strategy for the strangler fig transition.

02

Infrastructure and Project Scaffolding (1 Week)

We set up the parallel infrastructure that enables side-by-side execution. This includes: converting the solution to SDK-style project files, setting up a new .NET 8 solution structure alongside the existing .NET Framework projects, deploying the YARP reverse proxy with initial routing that sends all traffic to the legacy application, configuring the CI/CD pipeline to build and deploy both the legacy and modern applications, setting up shared authentication so that user sessions work across both backends, and configuring the database connection so both EF6 (legacy) and EF Core (modern) can operate against the same database concurrently. At this stage, the YARP proxy is live in production but routing 100% of traffic to the legacy backend — the infrastructure is proven before any migration code ships.

03

Shared Libraries and Data Access Migration (2-4 Weeks)

The foundation layers migrate first because every other module depends on them. We convert shared class libraries to multi-target projects (.NET Framework 4.8 and .NET 8) using conditional compilation where the APIs diverge. The data access layer is rebuilt on Entity Framework Core — model configuration, navigation properties, query translation differences, and migration history are all handled. We run EF6 and EF Core side-by-side against the same database and validate query output parity with automated comparison tests that execute the same business queries through both ORMs and diff the results. Domain models, DTOs, validation logic, and business rule libraries are ported to .NET Standard 2.0 where possible (consumed by both Framework and modern projects) or to .NET 8 where .NET Standard constraints are too limiting.

04

API and Service Layer Migration (3-6 Weeks)

Controllers, API endpoints, and background services are migrated module by module. Each module follows the same cycle: extract the bounded context into a new .NET 8 project, rewrite controllers from System.Web.Mvc or System.Web.Http to ASP.NET Core, replace WCF service references with gRPC clients or REST HttpClient calls, convert authentication middleware, wire up dependency injection using the built-in container, write integration tests that validate behavioral parity with the legacy implementation, deploy to staging behind YARP, run parallel traffic comparison (shadow mode) to verify identical responses, then flip the YARP route to send production traffic to the new service. Each module goes through this cycle independently. If a module has issues in production, the YARP route reverts to the legacy backend in seconds.

05

UI Layer Migration and Legacy Decommission (2-4 Weeks)

With all API endpoints and services running on .NET 8, the UI layer migrates last. Razor views are converted from the legacy view engine to ASP.NET Core Razor Pages or Blazor Server depending on the interactivity requirements. Bundling and minification pipelines are replaced with modern build tooling. JavaScript integrations are validated against the new backend. Once the UI layer is fully migrated and validated in production, the legacy .NET Framework application is decommissioned — all YARP routes now point to .NET 8 services, the IIS application pool is shut down, and the Windows Server instance can be replaced with Linux containers. Post-migration, we configure production monitoring with OpenTelemetry, set up health check endpoints for container orchestrators, and provide 30 days of hypercare support to catch any edge cases that surface under full production traffic.

Before vs After

MetricWith FreedomDevWithout
Hosting.NET 8: Linux containers, any cloud, $5/mo VPS to Kubernetes.NET Framework: Windows Server + IIS only ($1K-$6K/yr licensing)
Language VersionC# 12 — primary constructors, collection expressions, interceptorsC# 7.3 maximum — no pattern matching enhancements, no records, no top-level statements
Throughput (TechEmpower)ASP.NET Core: 7M+ plaintext req/sec, top-tier composite scoreASP.NET Framework: 200K-500K req/sec on equivalent hardware
Cold Start (Serverless).NET 8 Native AOT: <100ms cold start on AWS Lambda.NET Framework: not supported on Lambda/Functions at all
NuGet EcosystemFull access to current packages, source generators, analyzersEroding — Polly v8, MediatR 12+, many libraries dropped Framework support
SerializationSystem.Text.Json with source generation — zero reflection, AOT-safeNewtonsoft.Json — reflection-based, slower, cannot be AOT-compiled
GC and MemoryRegions-based GC, Span<T>, Memory<T>, array pooling, zero-copy parsingGen0/1/2 GC only, excessive heap allocations, no Span<T> without polyfills
Developer Talent PoolMajority of .NET developers in 2026 build on .NET 8 + LinuxShrinking pool of Framework specialists, higher rates, retention risk

Ready to Solve This?

Schedule a direct technical consultation with our senior architects.

Explore More

Legacy ModernizationCloud MigrationMicroservices ArchitectureAPI IntegrationManufacturingHealthcareFinancial ServicesLogistics

Frequently Asked Questions

How long does a .NET Framework to .NET 8 migration take?
Timeline depends on solution size, dependency complexity, and the number of Windows-specific APIs your application uses. A focused web application with 50K-100K lines of code, standard MVC controllers, Entity Framework 6, and no WCF services typically takes 2-3 months from assessment to legacy decommission. A large enterprise monolith with 300K+ lines of code, multiple WCF services, Windows Services, COM interop, and deep System.Web dependencies takes 4-8 months. The strangler fig approach means you do not need to wait until the full migration is complete to see value — each module ships to production on .NET 8 as it finishes, and your team begins benefiting from improved performance, modern tooling, and cross-platform deployment incrementally. The most important variable is not lines of code but dependency entanglement — a 200K LOC solution with clean project boundaries migrates faster than a 80K LOC solution where every class references System.Web.HttpContext.
Can we migrate incrementally or does it have to be all-at-once?
Incremental migration is the only approach FreedomDev recommends. The all-at-once rewrite — freeze features, rebuild everything, flip the switch on launch day — fails 60-80% of the time in practice. The strangler fig pattern with YARP reverse proxy lets you run both .NET Framework and .NET 8 simultaneously in production. YARP routes requests to the correct backend based on URL path, header, or other criteria. Each module is migrated independently: extract it into a .NET 8 project, validate behavioral parity, deploy behind YARP, flip the route. The legacy backend handles everything that has not been migrated yet. Your users never know a migration is happening. If a newly migrated module has issues, the YARP route reverts to the legacy implementation in seconds. This is the approach Microsoft recommends in their official migration documentation, and it is how every successful large-scale .NET migration we have seen has been executed.
What happens to our WCF services?
WCF is the hardest part of most .NET Framework migrations because it does not exist in .NET 8. Microsoft deliberately chose not to port WCF server hosting to modern .NET. CoreWCF — the community-maintained partial port backed by AWS and Microsoft — supports BasicHttpBinding and NetTcpBinding for teams that need a bridge during migration, but it does not cover WS-Security, WS-ReliableMessaging, MSMQ bindings, or many WCF behaviors and inspectors. For internal service-to-service communication, the migration target is gRPC: binary Protocol Buffers serialization, HTTP/2 transport, bidirectional streaming, and strongly-typed generated clients. gRPC throughput on .NET 8 is substantially higher than WCF NetTCP, and the proto-file-first contract model catches breaking changes at compile time instead of runtime. For public-facing endpoints where consumers expect HTTP/JSON, the migration target is ASP.NET Core Web API with OpenAPI documentation. We convert WCF DataContracts to DTOs, ServiceContracts to controller actions or gRPC service definitions, and rebuild the service implementations against the ASP.NET Core hosting model.
How do we handle Entity Framework 6 data access during migration?
EF6 and EF Core run side-by-side against the same database during the transition period. This is not a theoretical capability — it is how we execute every migration. The legacy modules that have not been migrated yet continue using EF6 against the production database. Newly migrated .NET 8 modules use EF Core against the same database. Both ORMs coexist because they operate at the application level, not the database level — the database does not know or care which ORM is generating the SQL. The migration itself requires careful attention to behavioral differences: EF Core defaults to no lazy loading (your code will break if it depended on transparent lazy navigation property loading), GroupBy translation was incomplete before EF Core 7, many-to-many join tables are implicit in EF Core instead of explicit, and the LINQ-to-SQL translation engine is completely different, meaning some EF6 queries produce different SQL or fail in EF Core. We validate with automated comparison tests that run identical business queries through both ORMs and diff the results at the row level.
What about Windows-specific code — Windows Services, COM interop, WPF, WinForms?
Windows-specific dependencies fall into three categories. First, Windows Services that handle background processing migrate to the BackgroundService base class in .NET 8, which runs as a hosted service inside the ASP.NET Core host and deploys to Linux containers — no Windows dependency, no sc.exe installation, no separate project. Second, COM interop is trickier: if your application calls COM components (often legacy DLLs for hardware integration, reporting engines, or industry-specific tools), those calls can only run on Windows. The options are wrapping the COM dependency behind an API that runs on a Windows container while the rest of the application runs on Linux, replacing the COM component with a .NET-native alternative, or accepting that this specific service stays on Windows as a sidecar. Third, WinForms and WPF desktop applications: both are supported on .NET 8 but remain Windows-only. If cross-platform is a goal, Blazor Server or Blazor WebAssembly replaces the desktop UI with a browser-accessible application, or .NET MAUI targets Windows, macOS, iOS, and Android from a single codebase. The decision depends on whether your users need offline capability, hardware access, or other desktop-specific features.
Will our existing NuGet packages work on .NET 8?
Some will, some will not, and some will work with caveats. Packages targeting .NET Standard 2.0 work on both .NET Framework 4.6.1+ and .NET 8 without changes — this is the bridge target that Microsoft designed for exactly this transition period. Packages that target .NET Framework directly (net45, net48, etc.) will not load in a .NET 8 project. Packages that have published .NET 8 targets (net8.0) will work with full platform support. The gray area is packages that technically load via .NET Standard compatibility but trigger platform compatibility analyzer warnings because they call APIs that behave differently or are missing on .NET 8. Our assessment phase includes a full package audit that categorizes every dependency: green (works as-is), yellow (works with warnings or behavioral changes), red (incompatible, replacement identified), and black (incompatible, custom replacement required). Common red-flag packages include anything depending on System.Web, System.Configuration.ConfigurationManager (replaced by Microsoft.Extensions.Configuration), and WCF client proxies (replaced by gRPC or REST clients).
What does the .NET Upgrade Assistant actually do versus what we still need engineers for?
The .NET Upgrade Assistant automates mechanical transformations: converting .csproj project files from the legacy verbose format to SDK-style, switching from packages.config to PackageReference, updating target framework monikers, replacing known API calls with their .NET 8 equivalents where a 1:1 mapping exists, and generating a compatibility report listing every breaking change, missing API, and deprecated pattern in your codebase. It is genuinely useful as a starting point and saves several days of tedious file-format conversion. What it cannot do is the actual migration engineering. It cannot redesign WCF service architectures as gRPC services. It cannot rewrite System.Web.HttpContext usage patterns to ASP.NET Core's fundamentally different request pipeline. It cannot convert EF6 data models to EF Core with correct configuration for the behavioral differences. It cannot decide whether your Windows Service should become a BackgroundService, a Hangfire job, or a separate container. It cannot refactor Global.asax lifecycle hooks into middleware. It cannot determine the correct module extraction order for strangler fig migration. It cannot write the YARP route configuration. The Upgrade Assistant is a diagnostic and scaffolding tool. The migration itself requires engineers who understand both the legacy and modern platforms.
How much does a .NET Framework to .NET 8 migration cost?
Cost scales with complexity, not just lines of code. A straightforward ASP.NET MVC application with 50K-100K lines of code, EF6 data access, no WCF, and clean project boundaries runs $40,000-$80,000 for the full migration including assessment, implementation, testing, and legacy decommission. Mid-complexity applications — 100K-300K lines of code, 2-5 WCF services, Windows Services, mixed EF6 and ADO.NET data access — run $80,000-$200,000. Large enterprise monoliths with 300K+ lines of code, deep System.Web entanglement, COM interop, multiple WCF service layers, and complex authentication run $200,000-$500,000+. The ROI calculation should include: Windows Server licensing eliminated ($1K-$6K per server per year), cloud compute cost reduction (30-50% from .NET 8 performance and Linux containers), developer productivity gains from modern tooling and language features, expanded hiring pool reducing recruitment costs, and reduced security risk from staying on a supported framework. Most organizations we work with see full payback within 12-18 months of completing the migration.

Stop Working For Your Software

Make your software work for you. Let's build a sensible solution.