ASP.NET Core - Routing



In MVC framework, we have three components, each with its own focus on a specific part of the job. In order for all of this to work, we need to find a way to send these HTTP requests to the right controller. In ASP.NET Core MVC, this process is known as routing. Routing is the process of directing an HTTP request to a controller.

Let us now understand how to route requests to different controllers.

  • The ASP.NET Core middleware needs a way to determine if a given HTTP request should go to a controller for processing or not.

  • The MVC middleware will make this decision based on the URL and some configuration information we provide. In this chapter, we will define this configuration information or you can say routing information inside Startup.cs when we add the MVC middleware.

  • This approach is often referred to as the convention-based routing. The following is a code snippet for conventional routing.

routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"); 
  • In this approach, we define templates that tell MVC how to look at a URL and find a controller name and an action name where a controller is a C# class and an action is a public method on that class.

In the last chapter, we have created a controller (HomeController) in our application which is a C# class and doesn’t need to be derived from a base class or implement an interface or have any special attribute. It is a plain C# class with a name, HomeController and it contains the Index method which returns a string.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks;  

namespace FirstAppdemo.Controllers { 
   public class HomeController { 
      public string Index() { 
         return "Hello, World! this message is from Home Controller..."; 
      } 
   }
}     

Here, we are going to focus on routing to controllers. We will also try understanding how routing works.

Let us now return to the Startup class where we configured MVC middleware into our application. Inside the Configure method, we have used a method UseMvcWithDefaultRoute.

public void Configure(IApplicationBuilder app) { 
   app.UseIISPlatformHandler();  
   
   app.UseDeveloperExceptionPage(); 
   app.UseRuntimeInfoPage();  
   
   app.UseFileServer(); 
   app.UseMvcWithDefaultRoute();  
   
   app.Run(async (context) => { 
      var msg = Configuration["message"]; 
      await context.Response.WriteAsync(msg); 
   });  
}

This gives us a default routing rule that allows us to get to the HomeController. Instead of using the UseMvcWithDefaultRoute, let us use the UseMvc, and then configure the route at this point using a named method ConfigureRoute. The following is the implementation of the Startup.cs file.

using Microsoft.AspNet.Builder; 
using Microsoft.AspNet.Hosting; 
using Microsoft.AspNet.Http; 

using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.Configuration; 
using Microsoft.AspNet.Routing; 
using System;  

namespace FirstAppDemo { 
   public class Startup { 
      public Startup() { 
         var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); 
         Configuration = builder.Build(); 
      }  
      public IConfiguration Configuration { get; set; } 
      
      // This method gets called by the runtime. 
      // Use this method to add services to the container. 
      // For more information on how to configure your application, 
      // visit http://go.microsoft.com/fwlink/?LinkID=398940 
      public void ConfigureServices(IServiceCollection services) { 
         services.AddMvc(); 
      }  
        
      // This method gets called by the runtime.  
      // Use this method to configure the HTTP request pipeline. 
      public void Configure(IApplicationBuilder app) { 
         app.UseIISPlatformHandler();  
         
         app.UseDeveloperExceptionPage(); 
         app.UseRuntimeInfoPage();  
         
         app.UseFileServer(); 
         app.UseMvc(ConfigureRoute);  
         
         app.Run(async (context) => { 
            var msg = Configuration["message"]; 
            await context.Response.WriteAsync(msg); 
         });
      }  
      private void ConfigureRoute(IRouteBuilder routeBuilder) { 
         //Home/Index 
         routeBuilder.MapRoute("Default", "{controller = Home}/{action = Index}/{id?}");
      }  
        
      // Entry point for the application. 
      public static void Main(string[] args) => WebApplication.Run<Startup>(args);
   } 
}  

Inside the ConfigureRoute method, you can configure your routes; you can see that this method has to take a parameter of type IRouteBuilder. The goal of routing is to describe the rules that ASP.NET Core MVC will use to process an HTTP request and find a controller that can respond to that request.

  • You can have one route that can map requests to different controllers.

  • We can tell the routeBuilder that we want to map a new route and its name is “Default” and then provide the most important piece of routing information, which is the template.

  • The template is a string, and it is going to describe to ASP.NET Core MVC how to pull apart a URL.

  • In the last example, we have added a HomeController, so you can also request any of the following URLs, and they will be directed to the Index action on the HomeController as well.

    • http://localhost:49940
    • http://localhost:49940/Home
    • http://localhost:49940/Home/Index
  • When a browser requests http://mysite/or http://mysite/Home, it gets back the output from the HomeController’s Index method.

  • You can try this as well by changing the URL in the browser. In this example, it is http://localhost:49940/, except that the port which might be different.

  • If you append /Home or /Home/Index to the URL and press the Enter button, you will see the same result.

  • The question mark at the end of ID means that this parameter is optional. In other words, ASP.NET Core MVC doesn't have to see some sort of ID here, which might be a number, or a string or GUID.

Let us run the application in the browser. Once the application is run, you will see the following output.

Output

You can see a message pop up from the app.Run middleware, and the reason we are getting this message is because the MVC middleware saw that URL. This was a request to the root of the website, which didn't find a controller name or an action name in the URL. The root of the website gave up processing that request and passed the request to the next piece of middleware, which is the app.Run code. The template for the route we have specified is quiet unlike the default template.

In the default template, there are some default values to apply if a controller and an action name aren't found. If a request comes in to the root of the website, the default controller name would be Home. You could change that to any other controller as you want and the default action name can be Index. You can also change the default action if you want as shown in the following program.

private void ConfigureRoute(IRouteBuilder routeBuilder) { 
   //Home/Index 
   routeBuilder.MapRoute("Default", "{controller = Home}/{action = Index}/{id?}"); 
}

If a request comes in to the root of the website, MVC doesn't see a controller/action type of URL, but it can use these defaults.

Let us save the Startup.cs file and refresh the browser to the root of the website.

Root Of the Website

You will now see a response from your controller and you can also go to /home which will invoke the default action, which is index. You can also go to /home/index and now MVC will pulling the controller name and action name out of the URL.

Let us create another controller by adding another class and call it AboutController.

About Controller

Let us add some simple action methods which will return string as shown in the following program.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks;  

namespace FirstAppDemo.Controllers  { 
   public class AboutController { 
      public string Phone() { 
         return "+49-333-3333333"; 
      }  
      public string Country() { 
         return "Germany"; 
      } 
   } 
} 

In this controller, you can see two actions methods − Phone and Country, which will return just a phone number and country name respectively. We'll get into fancy HTML later. Let us save this file and specify /about/phone at the end of the root URL.

Two Action Methods

You can see the phone number as in the above screenshot. If you specify /about/country, you will see the name of the country too.

Country Name

If you go to /about, it is again going to fall through the middleware and go to your app.Run middleware and you will see the following page.

About

Here, the ASP.NET Core MVC goes to the AboutController, but does not find an action specified. So it will default to Index and this controller doesn't have an Index method and then the request will go the next piece of middleware.

Advertisements