Routing is a pattern matching system that monitors the incoming request and figures out what to do with that request. At runtime, the routing engine uses the route table for matching the incoming request's URL pattern against the URL patterns defined in the ‘Route Table’.
Before MVC routing, we were using URL Rewriting technique. This technique is used in the ASP.NET application where the requested URLs are typically searched for in a physical file. The application handles the request which contains requested code and markup for sending response to the browser.
For example, if the URL is http://server/application/Users.aspx?id=4 then, this URL maps to the physical file Users.aspx to get the response for the browser.
To serve a specific request, the system needs to have the physical file for the same but as we all know an application written with MVC architecture does not have a physical file to handle the request.
Hence, to handle this request MVC has its own routing mechanism to handle the request. The routing mechanism decides the method which is to be called from the controller to handle the request.
The following code shows how to register a route in MVC:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
At the time of executing an application Application_start Eventhandler of Global.aspx gets called where registration of ‘area, filter and route’ has been done.
It is to be noted that, the ‘area’ here should always get registered first to apply the routes on the ‘area’. In the same event, there is a function called RegisterRoutes (in red) to register all routes when the application execution happens for the first time.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
When RegisterRoutes gets called from Application_start, the RouteTable class calls Route Collection and passes it to RegisterRoutes method to register the route in the application. The same method also prevent requests for the web resource files such as WebResource.axd and ScriptResource.axd from being passed to a controller by adding the route with the pattern {resource}.axd/{*pathInfo}.
At the time of launching, all routes get initialized and as we can see in the above code, MapRoute method is called with three parameters:
'Name, URL, Default'.
Name parameter is used to specify the route name.
URL contains three placeholders. (URL segments are separated by '/')
To set 'default' values for a route by assigning a dictionary object to the Defaults property of the Route class.
When a request hit the server first time it gets routed to the object of UrlRoutingModule and then to MVCHttpHandler which determines which controller should get called by adding "Controller" to the controller value of URL placeholder. Once it determines the controller, the value of action placeholders determines which action to call.
Route Constraints:
We can also provide restriction to the route by adding constraint to meet route criteria. It is provided by using regular expressions. We can provide a separate
regular expression to each placeholder to check. Each placeholder checks the requested value against provided regular expression and by using IsMatch method of the Regex class. The Match method returns a Boolean value that indicates whether the parameter value is valid.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = "^H.*", action = "^Index$|^Contact$" } //Restriction for controller and action
);
}
Multiple requests to the same action:
To change the original URL of the request, we can use MapLocalizedRoute or mapRoute to change.
To implement this, we need to create a new class while implementing the IRouteProvider interface.
routes.MapLocalizedRoute("Login",
"Login/",
new { controller = "Account", action = "Login" },
new[] { "App.Web.Controllers" });
The first parameter would be a name of route.
The second paratmeter would be a New URL.
The third parameter would be an object which will be specifying which action from which controller should get called.
The fourth parameter would be namespace of that method.
Hence this is how routing works for an application in a MVC context.