[ASP.NET MVC] Routing – Incoming URLs

In ASP.NET Web Forms, an “URL” points to the real physical file in the web server. It is not true for MVC. The MVC Routing module maps the incoming requests to MVC controller actions. A controller is mapped to a controller class and an action is to a method.

 

1. Default Routing Table

The “Web.config” file has settings related to routing. But the routing table is created in the “Global.asax“.

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
        }
    );
  }
}
protected void Application_Start()
{
  RouteConfig.RegisterRoutes(RouteTable.Routes);
}

The default routing table is created when a ASP.NET process starts. The default route maps the URL to 3 parameters:

  • controller : controller class name
  • action : method name
  • id : additional parameter

For example, if the URL is “mysite.com/Home/Index/1”, the URL is mapped to the “Index” action method of the “HomeController” class with a parameter “id=1”.

 

2. Creating Custom Routes

If you are developing a real production site, the default route pattern will not be sufficient to map all possible requests to your controllers. You can create custom routes in the static “RegisterRoutes()” method.

In most cases, you will use the “routes.MapRoute()” method to add a new route. The “MapRoute()” method is an extension method targeted for “System.Web.Routing.RouteCollection” class and defined in the “System.Web.Mvc.RouteCollectionExtensions” class. The “MapRoute()” method can have the following parameters:

  • name
  • url
  • defaults
  • constraints

You can add multiple routes to the “RouteCollection“. But the order matters and the first match always wins.

 

3. URL Patterns

A URL pattern can contain literal values and placeholders for parameters. Placeholders are enclosed in braces.

Typically MVC URLs include {controller} and {action} placeholders. The “MvcHandler” (HTTP handler) determines which controller to invoke by adding the suffix “Controller” to the {controller} value. The {action} value in the URL determines which action method to call.

 

4. Default Parameter Values

Parameters can have defaults. Even you can specify the default value to the parameter that does not exist in the url pattern. Default values are supplied as properties in an anonymous type.

routes.MapRoute(
  "blog",
  "blog/{action}/{id}",
  new { controller = "Blog", action = "Index", id = "1" }
 );

If the request url is “/blog”, the “Index” action of the “BlogController” will be invoked with an id=1.

 

5. Route Constraints

As a last argument of the “MapRoute()” method, you can pass constraints of url parameters.

The “blog” route in section 4 includes the {id} parameter. What if you only want an integer value for a blog id? Unfortunately, any value will be mapped to {id}.

Constraints are regular expressions that are used to restrict paramters to specific formats.

routes.MapRoute(
  "Default",
  "{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = "" },
  new { id=@"\d+" }
);

 

6. Catch-All Parameters

The catch all parameter “{*param_name}” allows catch all of the remaining part of an URL.

For example, when the url pattern is “blog/view/{*blogAddr}”, the “blogAddr” parameter of the following requests will be:

  • “/blog/view/a/b/c”:   “a/b/c”
  • “/blog/view/a/b”:      “a/b”
  • “/blog/view/a”:          “a” 
  • “/blog/view”:               “”

 

7. Greedy Matching

Suppose you create a route “{filename}.{ext}” to find out the file name and extension as parameters.

What if the request is “mydoc.2010.txt”? What is assigned to the “filename” or the “ext”?

The route match engine uses so-called “Greedy Matching“: parameters take the part of url as much as possible. In our example, the first parameter “filename” takes “mydoc.2010”, not just “mydoc”.

  • “mydoc.may.2010.txt”:  “mydoc.may.2010” and “txt”
  • “mydoc.2010.txt”:           “mydoc.2010” and “txt”
  • “mydoc.txt”:                     “mydoc” and “txt”

 

8. RouteData

You can access the route values in an action methods in 2 ways: method parameters and “RouteData” dictionary.

  • public RouteData RouteData { get; set; }

The “System.Web.Routing.RouteData” class has the “Values” property to acess route data values.

  • public RouteValueDictionary Values { get; }
public ViewResult DoSomething(int id)
{
  ViewBag.ID = id;
  return View();
}
public ViewResult DoSomething()
{
  ViewBag.ID = RouteData.Values["id"];
  return View();
}

 

9. Bypassing the Routing System

The “IgnoreRoute()” method is defined as an extension method for the “RouteCollection” class.

  • public static void IgnoreRoute(this RouteCollection routes, string url)
  • public static void IgnoreRoute(this RouteCollection routes, string url, Object constraints)

The specified URL route will be ignored by the Routing system.

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  routes.IgnoreRoute("Content/{filename}.html");
  ...
}

If the URL pattern passed to the IgnoreRoute() method matches, then no subsequent routes will be evaluated. Therefore, it is very important that where the IgnoreRoute method is placed.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s