Learn how to implement endpoint routing in ASP.NET Core 3.0 MVC to bring more flexibility and functionality to your applications Credit: Koto Feja / Getty Images ASP.NET Core MVC is the .NET Core counterpart of the ASP.NET MVC framework. You can take advantage of ASP.NET Core MVC to build cross-platform, scalable, high-performance web applications and APIs using the Model-View-Controller design pattern. ASP.NET Core takes advantage of routing to map incoming requests to respective controller actions. You can learn the basics of routing in ASP.NET Core from my earlier article, “Demystified: Routing in ASP.NET Core.” This article presents a discussion of how we can use endpoint routing in ASP.NET Core 3.0 MVC. Endpoint routing is a feature newly introduced in ASP.NET Core that enables you to provide routing information to middleware in the request processing pipeline. Before the introduction of endpoint routing, routing resolution in ASP.NET Core MVC was performed at the end of the request processing pipeline. As a result, route information (such as which action method needs to be executed) was unknown to any middleware processing a request before the MVC middleware in the request processing pipeline. Incidentally, endpoint routing is available as part of ASP.NET 3.0 and later versions. Endpoint routing matches HTTP requests to endpoints early in the middleware pipeline instead of at the end. This allows middleware later in the pipeline to access the resolved endpoint and apply additional processing. In other words, endpoint routing decouples the route matching and endpoint dispatching functions, giving you the flexibility to combine different middleware (MVC, CORS, Razor Pages, Blazor, etc.) in your applications. To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t have a copy of it, you can download Visual Studio 2019 here. Create an ASP.NET Core MVC project First off, let’s create an ASP.NET Core project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new ASP.NET Core MVC project in Visual Studio. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “ASP.NET Core Web Application” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. Click Create. In the “Create a New ASP.NET Core Web Application” window, select .NET Core as the runtime and ASP.NET Core 3.0 (or later) from the drop-down list at the top. Select “Web Application (Model-View-Controller)” as the project template. Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here. Ensure that Authentication is set as “No Authentication” as we won’t be using authentication either. Click Create. This will create a new ASP.NET Core project in Visual Studio. We’ll use this project to implement endpoint routing in the subsequent sections of this article. Create a new controller in ASP.NET Core 3.0 MVC In the Solution Explorer Window, select the Controllers folder in the project, right-click and then click on Add->Controller… to create a new controller. Specify the name of the controller class as AuthorController. Next, replace the code of the AuthorController class with the following code. [Route("api/[controller]")] [ApiController] public class AuthorController : ControllerBase { readonly Repository repository = new Repository(); [HttpGet] public ActionResult GetAuthors() { var records = repository.GetAllAuthors(); return Ok(records); } } We’ll use the AuthorController in the subsequent sections of this article. Understand routing in ASP.NET Core Routing is a feature that exposes endpoints and matches incoming HTTP requests to your controller’s action methods. The routing middleware pertaining to the Microsoft.AspNetCore.Routing namespace is responsible for handling requests and responses, inspecting requests and matching them to endpoints, and even modifying the request and response messages that flow through the request processing pipeline. Convention routing vs. attribute routing You can specify routing in your action methods in two different ways — convention-based routing and attribute-based routing. The following code snippet illustrates how you can use convention routing in the Configure method of the Startup class. app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Author}/{action=GetAuthors}/{id?}"); }); When using attribute-based routing you would mention route on your controller or the action method. You can define multiple routes for the same action method. Here is an example that illustrates this. public class AuthorController : Controller { [Route("")] [Route("Home")] [Route("Home/Index")] public IActionResult Index() { return View(); } [Route("Home/GetAuthor/{id:int}")] public IActionResult GetAuthor(int id) { ViewBag.Id = id; return View(); } } Route definitions in ASP.NET Core 3.0 MVC When you create a new ASP.NET Core 3.0 MVC application, a default route will be created for you by Visual Studio. This is how it would look. app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); } The route definition shown here consists of two parameters — the name of the route and the route pattern. This route will match the following URLs. /Home/Index /Author/Index /Author/Index/12 UseRouting vs. UseEndpoints in ASP.NET Core 3.0 MVC Routing takes advantage of a pair of middleware components that are registered using the UseRouting and UseEndpoints extension methods. While the former is used to match a request to an endpoint, the latter is used to execute a matched endpoint. Note that the UseRouting middleware should be configured ahead of all other middleware including authentication, authorization, and any custom middleware. By contrast, the UseEndpoints middleware should be configured at the end. The following code snippet illustrates this. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Author}/{action=GetAuthor}/{id?}"); }); } If you want to check the route metadata at runtime, you can use the following code and debug it in Visual Studio. app.Use(async (context, next) => { var endPoint = context.GetEndpoint(); var routes = context.Request.RouteValues; }); Configure routing in ASP.NET Core 3.0 MVC You can set up routing in your ASP.NET Core 3.0 MVC application easily. For this you would need to make a couple of changes to the Startup class. First off, you should call the AddRazorPages method as shown below. public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); } Next, you should call the MapRazorPages method as shown below. This method when called will add the Razor Pages services, options, and conventions to the pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //Usual code app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Author}/ {action=GetAuthor}/{id?}"); }); } Use named routes in ASP.NET Core 3.0 MVC Note that you can specify a name for a route so that you can use multiple routes having the same parameters. Such routes are known as named routes. The following code snippet illustrates how named routes can be used. app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Author}/{action=GetAuthors}/{id?}"); } Set route defaults in ASP.NET Core 3.0 MVC You can also explicitly set route defaults as shown in the code snippet below. endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action}/{id?}", defaults: new {controller = "Home", action = "Index"}); Use MapRazorPages in ASP.NET Core 3.0 MVC You can take advantage of the MapRazorPages extension method to enable routing for your Razor view pages. The following code snippet shows how this can be achieved. app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); Use mixed routing in ASP.NET Core 3.0 MVC Note that you can use attribute-based routing for some controllers and actions and convention-based routing on other controllers and action methods. Although it is perfectly valid to use both, it should be noted that you cannot have attribute-based routing and convention-based routing in the same action method. ASP.NET 3.0 gives us an extensible and modular framework for working with endpoints, URLs, and middleware. I’ll discuss routing in more depth in a future article here. We’ll explore the advanced routing features in ASP.NET Core 3.0 such as route templates, route constraints, custom route constraints, and more. How to do more in ASP.NET and ASP.NET Core: How to use in-memory caching in ASP.NET Core How to handle errors in ASP.NET Web API How to pass multiple parameters to Web API controller methods How to log request and response metadata in ASP.NET Web API How to work with HttpModules in ASP.NET Advanced versioning in ASP.NET Core Web API How to use dependency injection in ASP.NET Core How to work with sessions in ASP.NET How to work with HTTPHandlers in ASP.NET How to use IHostedService in ASP.NET Core How to consume a WCF SOAP service in ASP.NET Core How to improve the performance of ASP.NET Core applications How to consume an ASP.NET Core Web API using RestSharp How to work with logging in ASP.NET Core How to use MediatR in ASP.NET Core How to work with session state in ASP.NET Core How to use Nancy in ASP.NET Core Understand parameter binding in ASP.NET Web API How to upload files in ASP.NET Core MVC How to implement global exception handling in ASP.NET Core Web API How to implement health checks in ASP.NET Core Best practices in caching in ASP.NET How to use Apache Kafka messaging in .NET How to enable CORS on your Web API When to use WebClient vs. HttpClient vs. HttpWebRequest How to work with Redis Cache in .NET When to use Task.WaitAll vs. Task.WhenAll in .NET Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos