From an on-prem .NET Framework 4.5 app to .NET 10 on Azure
This is a representative plan for a common starting point: a monolithic ASP.NET WebForms or MVC application on .NET Framework 4.5, running on an on-prem IIS server, with a direct SQL Server dependency and no automated deployment. It shows the actual sequence of work, not just the end state.
- ASP.NET WebForms/MVC on .NET Framework 4.5
- Hosted on an on-prem Windows Server + IIS
- Direct SQL Server connection, no data access layer
- Manual deployment via RDP and file copy
- No automated tests
- Single developer holds most system knowledge
- Blazor on .NET 10
- Azure App Service, deployed via CI/CD
- Entity Framework Core data access layer
- Automated build, test, and release pipeline
- Core regression test suite in place
- System knowledge documented and shared
Five phases, each shipping something real
No phase depends on "finishing the rewrite" to deliver value. The application stays live and usable throughout.
Audit
1–2 weeksMap what the system actually does before touching any code.
- Inventory all pages, controllers, and background jobs, and flag any with no clear owner
- Trace direct SQL dependencies and stored procedure usage against the codebase
- Identify third-party libraries and NuGet packages with no .NET 10-compatible version
- Document authentication, session state, and any Windows-specific dependencies (e.g. System.Web, IIS modules)
- Rank modules by business risk and change frequency to sequence later phases
Plan
1 weekTurn the audit into an ordered, phased migration path.
- Group the application into vertical slices (e.g. by feature area) that can migrate independently
- Choose the strangler fig pattern: new Blazor app runs alongside the legacy app during transition, routed by URL path or subdomain
- Define the target Azure App Service tier, region, and networking (VNet integration if the on-prem SQL Server needs a private connection during transition)
- Agree rollback criteria for each phase before work starts on it
Refactor
Ongoing, per sliceMove logic and UI into the new stack, one vertical slice at a time.
- Introduce Entity Framework Core against the existing SQL Server schema, without altering it yet
- Rebuild the highest-risk, most-changed slice first in Blazor, reusing existing business logic where it's sound
- Extract inline SQL and business rules from code-behind files into testable service classes
- Write regression tests for the slice being migrated before changing its behavior
- Keep the legacy app serving every slice not yet migrated, routed via the strangler pattern from Phase 2
Deploy
Ongoing, per sliceShip each slice behind a CI/CD pipeline, validated against legacy behavior.
- Stand up Azure DevOps or GitHub Actions pipeline: build, run automated tests, deploy to a staging App Service slot
- Use App Service deployment slots to swap staging into production with zero downtime
- Run the migrated slice in parallel with the legacy version briefly, comparing output where practical
- Cut over DNS/routing for that slice once validated; keep the legacy code path available as a fallback for a defined window
Support
OngoingDecommission the old system and keep the new one from becoming tomorrow's legacy.
- Once every slice has migrated, decommission the on-prem server and legacy IIS deployment
- Set up Azure Monitor and Application Insights for the App Service, replacing informal error reporting
- Schedule regular dependency and .NET version updates so the app doesn't drift back into legacy status
- Hand over documentation covering architecture, deployment process, and known technical decisions
Want a plan like this for your own system?
Every migration starts with an audit specific to your codebase, not a generic template. The Stack Assessment is a fast first look; a full audit goes deeper.
// or contact us to discuss your system directly