Keywords: ASP.NET Core | Endpoint Routing | UseMvc | Routing Migration | .NET Core 3.0
Abstract: This technical article examines the compatibility warning between 'UseMvc' and Endpoint Routing during ASP.NET Core 2.2 to 3.0 migration. Through detailed analysis of architectural differences between endpoint-based and IRouter-based routing systems, it presents three resolution strategies: replacing UseMvc with UseEndpoints, using AddControllers with MapControllers, or disabling endpoint routing. The article provides comprehensive code examples and explains the middleware workflow and performance benefits of endpoint routing, offering complete migration guidance for developers.
Problem Background and Warning Analysis
During the migration from ASP.NET Core 2.2 to 3.0 Preview 8, many developers encountered a critical warning: "using 'UseMvc' to configure MVC is not supported while using Endpoint Routing". This warning indicates architectural conflicts between the traditional UseMvc method and the new endpoint routing system.
Core Differences Between Endpoint Routing and IRouter Routing
Endpoint routing in ASP.NET Core 3.0 introduces a fundamentally new routing architecture that differs significantly from the traditional IRouter-based system. In traditional routing, the UseMvc method processes request routing through RouteBuilder and MvcRouteHandler, relying on route matching and execution within the middleware pipeline.
Endpoint routing adopts a more modular and high-performance design. When EnableEndpointRouting is set to true (the default in 3.0), the system utilizes EndpointMiddleware for routing processing. This design enables pre-computation of all endpoint information during application startup, including route templates, constraints, and policies, resulting in faster matching performance during request processing.
Detailed Implementation of Three Solutions
Solution 1: Complete Replacement of UseMvc with UseEndpoints
This is Microsoft's recommended modern approach. First, register MVC services in ConfigureServices:
services.AddMvc();Then use endpoint routing in the Configure method:
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
});This approach leverages the performance optimizations of endpoint routing while maintaining compatibility with traditional routing configurations.
Solution 2: Using AddControllers with MapControllers Combination
For applications using only controllers without Razor Pages, a more lightweight approach is available:
// In ConfigureServices
services.AddControllers();
// In Configure
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});The MapControllers method automatically discovers and registers all controllers using attribute routing, simplifying the configuration process.
Solution 3: Disabling Endpoint Routing (Backward Compatibility)
If the application depends on certain legacy routing features or requires gradual migration, endpoint routing can be temporarily disabled:
services.AddMvc(options => options.EnableEndpointRouting = false);This method allows continued use of UseMvc but sacrifices the performance benefits of endpoint routing, recommended only as a temporary solution.
In-depth Architectural Analysis
From a source code perspective, when EnableEndpointRouting is true, the system creates MvcEndpointDataSource to manage all controller endpoints. Each route is converted into an MvcEndpointInfo object containing complete route metadata. This design enables authorization, CORS, and other policies to participate in decision-making during the route matching phase, rather than during request processing.
In contrast, traditional routing uses RouteBuilder and MvcRouteHandler, where route matching and execution are separated. This separation incurs additional performance overhead, particularly in complex routing scenarios.
Migration Recommendations and Best Practices
For new projects, strongly adopt Solution 1 or 2 to fully leverage the modern features of endpoint routing. For existing project migrations:
- First test if the application functions correctly with endpoint routing disabled
- Gradually migrate routing configurations to
UseEndpoints - Utilize new endpoint routing features like route constraints and parameter policies
- Update unit tests to accommodate the new routing architecture
Endpoint routing not only addresses performance issues but also provides better foundational architecture support for ASP.NET Core's future evolution.