microsoft/migrating-mvc-routing
> Converts ASP.NET MVC RouteCollection-based routing to ASP.NET Core endpoint routing with MapControllerRoute in Program.cs. Use when migrating RouteConfig.cs, RouteTable.Routes, routes.MapRoute, routes.MapMvcAttributeRoutes, or RouteCollection to ASP.NET Core. Also triggers for MVC routing upgrade, endpoint routing migration, and conventional route conversion.
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill migrating-mvc-routing
Migrate ASP.NET MVC routing from RouteCollection/RouteConfig.cs to ASP.NET Core endpoint routing in Program.cs.
Migration Progress:
- [ ] Step 1: Locate route registration
- [ ] Step 2: Convert to ASP.NET Core routing
- [ ] Step 3: Handle MVC + API controllers
- [ ] Step 4: Preserve existing customizations
- [ ] Step 5: Remove RouteConfig
Find all route registration code. Typically lives in RouteConfig.cs:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcAttributeRoutes();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Catalog", action = "Index", id = UrlParameter.Optional }
);
}
}
Default routes (no customization): Replace with:
app.MapDefaultControllerRoute();
Custom routes: Add MapControllerRoute calls in Program.cs. Inline defaults and optional parameters into the pattern string because ASP.NET Core uses pattern tokens instead of a separate defaults object:
// Old: url: "{controller}/{action}/{id}", defaults: new { controller = "Catalog", action = "Index", id = UrlParameter.Optional }
// New:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Catalog}/{action=Index}/{id?}");
| Old (RouteCollection) | New (ASP.NET Core) |
|-----------------------|--------------------|
| url: "{controller}/{action}/{id}" | pattern: "{controller}/{action}/{id?}" |
| defaults: new { controller = "Home" } | pattern: "{controller=Home}" |
| defaults: new { action = "Index" } | pattern: "{action=Index}" |
| id = UrlParameter.Optional | {id?} |
| routes.MapMvcAttributeRoutes() | app.MapControllers() |
If the project has both MVC and API controllers, register both attribute and conventional routing. Call app.MapControllers() before app.MapControllerRoute() so attribute-routed API controllers take precedence over conventional routes — otherwise conventional routes could intercept API requests:
app.MapControllers(); // Attribute routing for API controllers
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Keep any existing routing middleware on the application object and add new routes alongside it. Carry over method-chained customizations like .RequireSystemWebAdapterSession():
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}")
.RequireSystemWebAdapterSession();
RouteConfig.cs (or equivalent file containing RegisterRoutes). Only delete if it contains no non-routing logic.RouteTable.Routes across the codebase.using statements and class references.RouteTable.Routes references remainTake microsoft/migrating-mvc-routing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.