It is not a straightforward version bump to upgrade an ASP.NET MVC application from the.NET Framework to the current.NET. The runtime, hosting model, configuration system, dependency injection, and HTTP pipeline architecture have all changed as a result of this migration. Many teams undervalue this and handle it like a typical framework upgrade, only to find out later on that their application's fundamental presumptions are no longer valid.

The good news is that Microsoft provides clear guidance and patterns that make this migration predictable when approached correctly. This article walks through a practical, step by step strategy to migrate an ASP.NET MVC 5 application built on .NET Framework to ASP.NET Core running on modern .NET, while minimizing risk and downtime.

This guide is written for developers who already understand ASP.NET MVC and want a realistic, production ready path forward.

Step 1: Choose your migration path based on app size

  • Pick one of these two paths
  • Incremental migration for most real apps
    You stand up a new ASP.NET Core app in front of the old app and move routes and features over gradually, keeping the old app live while you migrate. Microsoft recommends this approach for large migrations.
  • Big bang migration for small apps 
    You create a new ASP.NET Core MVC app and port controllers, views, and services until everything runs, then you cut over.

If you are unsure, default to incremental migration because it reduces cutover risk.

Step 2: Inventory what will block you
List dependencies and app features that commonly need work during migration

  • System.Web usage
    Things like HttpContext.Current, HttpModules, HttpHandlers, Global.asax, and classic pipeline features do not carry over as is.
  • Authentication and authorization
    ASP.NET Core uses a different model.
  • Session, caching, config, logging
    APIs and patterns differ and need deliberate migration planning.

Make a quick compatibility pass on your NuGet packages

  • For each package, check if it supports netstandard2.0 or modern net versions, or if there is an ASP.NET Core replacement.
  • Flag anything tied to System.Web.

Step 3: Create a safe baseline before touching code

  • Freeze the current state
    • Tag the repo.
    • Ensure you can build the solution and run your test suite.
  • Add or strengthen tests if you are light on coverage
    • Focus on critical routes, auth flows, and the top business actions.
    • If you cannot add tests quickly, at minimum record smoke test scripts and expected outputs.

Step 4: Upgrade libraries first, before the web app
This is the highest leverage move.
Split your solution into layers, if it is not already

Web project, application services, domain, data access, shared utilities.

Port class libraries first

Convert libraries to target netstandard2.0 when possible as a bridge, or target modern .NET directly if you can.

Fix compile errors and replace unsupported APIs.

Microsoft’s general porting guidance is to assess the project and move pieces in a way that reduces complexity after the initial upgrade.

Step 5: Decide whether to use migration tooling

You have two Microsoft supported tool directions you can use to speed up parts of the work.

  • .NET Upgrade Assistant
    It helps upgrade projects and analyze incompatibilities, including .NET Framework projects. Use it where it helps, but do not expect it to fully transform an ASP.NET MVC 5 app into ASP.NET Core MVC automatically.
  • Migration tooling for ASP.NET Framework apps
    Microsoft points to dedicated modernization tooling for upgrading ASP.NET Framework MVC, Web API, and Web Forms projects to ASP.NET Core.

You can still do everything manually if you prefer, but tooling can reduce boring mechanical edits.

Step 6: Create the new ASP.NET Core MVC host app

This step is required even in incremental migration because you need an ASP.NET Core app to run on modern .NET.

Create a new ASP.NET Core MVC project

  • Use the standard ASP.NET Core MVC template.
  • Add your core packages, logging, config, and DI structure.

Set up the modern entry point

  • In ASP.NET Core, Program.cs configures the host and middleware pipeline.
  • There is no Global.asax.

Add basic middleware you will definitely need

  • Routing
  • Static files
  • Authentication and authorization, if applicable
  • MVC endpoints

Minimal example shape:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Step 7: Move routes first, then controllers, then views
Microsoft’s MVC to Core example walkthrough starts with setup, then controllers and views, then static content and client dependencies. Follow that order because it keeps the migration testable at every step.

Migrate routing

  • In MVC 5 you likely used RouteConfig and possibly attribute routes.
  • In ASP.NET Core you configure routing in the middleware pipeline and endpoint mappings.

Migrate one controller at a time

  • Copy a controller class.
  • Fix compile errors by switching namespaces and replacing System.Web dependent code.
  • Replace HttpContext.Current patterns with controller HttpContext access.

Migrate views

  • Razor syntax is similar, but helpers and some features differ.
  • Convert HTML helpers where needed, and use Tag Helpers where it makes sense.

Migrate partials, layouts, and shared view imports

  • You will likely introduce ViewImports.cshtml and ViewStart.cshtml patterns.

Step 8: Move static files and client side dependencies

  • Static files
    • In MVC 5 you may have used Content and Scripts conventions.
    • In ASP.NET Core, the default is wwwroot plus UseStaticFiles middleware.
  • Bundling and minification
    If you relied on System.Web.Optimization, replace it with a modern frontend build pipeline or another supported approach.

Microsoft’s example migration flow explicitly calls out static content and client side dependencies as an early migration step.

Step 9: Migrate configuration from Web.config to appsettings

  • Identify what you store in Web.config
    • Connection strings
    • App settings
    • Authentication settings
    • Custom config sections
  • Move settings into appsettings.json and environment specific appsettings files
  • Read settings using the ASP.NET Core configuration system via builder.Configuration

Microsoft has dedicated guidance linked from the MVC migration example for migrating configuration.

Step 10: Migrate authentication and authorization
Identify your current auth model

  • Forms auth
  • OWIN cookies
  • ASP.NET Identity in MVC 5
  • Windows auth

Implement the equivalent in ASP.NET Core

  • Configure authentication services in DI.
  • Add middleware in the pipeline.
  • Port authorization attributes and policies.

Microsoft’s MVC migration example points to dedicated guidance for migrating authentication and Identity because it is usually one of the heavier parts.

Step 11: Migrate data access
If you use Entity Framework 6

  • You can often keep EF6 for a while, even on modern .NET, depending on your setup.
  • Longer term, many teams move to EF Core for modern patterns and features.

If you use ADO.NET or Dapper
These typically port cleanly, but you will update configuration and dependency injection patterns.

Step 12: Run the app, fix runtime issues, then optimize

Build and run locally

Fix runtime issues in this typical order

    Configuration and environment differences

    Middleware ordering problems

    Auth and cookies

    Session and caching behavior

Run automated tests and smoke tests

Add structured logging and health checks where appropriate

Step 13: If you chose incremental migration, set up the “front door” Core app

For incremental migration, the key move is putting an ASP.NET Core app in front of the existing .NET Framework app and migrating route by route. Microsoft’s “get started” guidance for incremental migration recommends this proxy front approach for large migrations.

Your process becomes:

Route A handled by ASP.NET Core, everything else proxies to MVC 5

Move one vertical slice at a time

When all routes are moved, retire the old MVC 5 app

Step 14: Production cutover checklist

Hosting
Decide IIS in process, IIS out of process, or container.

Observability
Logs, metrics, tracing aligned across both apps during incremental migration.

Security
Cookie settings, data protection keys, TLS, headers

Performance
Confirm caching and session behavior after migration.

Final Thoughts
Migrating an ASP.NET MVC application from .NET Framework to modern .NET is a strategic investment, not a mechanical upgrade. When done correctly, it results in a cleaner architecture, improved performance, better cloud readiness, and long term platform support.By breaking the migration into deliberate, testable steps and focusing first on architecture rather than syntax, teams can modernize confidently without disrupting production systems.

This approach has proven to work repeatedly in real world enterprise migrations and aligns with Microsoft’s recommended modernization strategy for ASP.NET applications.