Explain ASP.Net MVC Routing With Example

This article describes how ASP.NET MVC routing works, Custom Routes, attribute routing, route constraints, Area Routing.

This gives you a detailed description of ASP.NET MVC request steps like routing, MvcHandler, Controller, Action Execution, View Result, View Engine, and View.

ASP.NET MVC routing

Routing is an important feature of ASP.NET MVC. The routing module is responsible for mapping incoming browser requests to a unique controller action method. Routing is an entry point of ASP.NET MVC Request life cycle

Below picture shows how ASP.NET MVC handles requested URL

asp.net mvc routing

Routing data gets filled in the Application_Start event. It uses the RouteTable objects to fill routes. The routing engine uses this table to match incoming requests and execute action methods.

You can add route details to the application by adding the Route object to the static Routes property of RouteTable. Route property is a RouteCollection object.

Below is an example of adding routes to RouteTable. You can use the Global.asx file or RouteConfig.cs from the App_Start folder to add Routes.

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
             
        routes.MapRoute(
            "Order",    // Route name
            "orders/{controller}/{action}/{id}",// URL with parameters
            new { controller = "order", action = 
                    "Index", blogid = "" }  // Parameter defaults
        );   

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index",
                 id = "" }  // Parameter defaults
        );
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

        

I have used Global.asax file. I added two routes with name order and default.

All below URLs will match the Order route.

  • http://example.com/orders/customer/showorder/4567
  • http://example.com/orders/customer/updateorder/4567
  • http://example.com/orders/customer/placeorder
  • http://example.com/orders/report/orders
  • http://example.com/orders/report/customer
  • http://example.com/orders/report/customer/4567

Notice that each URL has orders before any other part of the URL and the route which is added with the name Order has similar URL parameters. Some of the URLs listed above do not have id parameter, still, it is taken care of by Order route as default empty string has provided to the id parameter.

URLs that are not mapped by the first route, will be mapped to the default route. Here the second route is the most generic route and will be used for all other URLs.

Below urls will be matched by default route.

  • http://example.com/customer/showorder/4567
  • http://example.com/order/showorder/4567
  • http://example.com/order/showorders
  • http://example.com/home/index
  • http://example.com/home
  • http://example.com

You can also mix path segments with route parameters however you cannot have two consecutive route parameters.

The following routes are valid.

  • {language}-{country}/{controller}/{action}
  • {controller}-{action}-{id}
  • {controller}.{action}.{id}

However, the below route is invalid as there is no way for the route to know when the controller part of the incoming request URL ends and when the action part should begin.

  • {controller}{action}/{id}

Custom Routing ASP.NET MVC

For most of the request, your applications default route will work fine, however, you might see different needs to which are not satisfied by default routing.

Below are some examples where you need custom routing

  • URL has date and date should be in a specific format e.g. 12-10-2014
  • URL has id which should be integer.
  • The request should be HTTP Post method.
  • The request should be coming from local
  • The request has {Area} segment.

You can also create Custom routing modules when you need to treat requests to PDF / txt / html files differently. You can override GetRouteData and GetVirtualPath of Route class.

Attribute Routing

Attribute Routing is a new type of routing feature of ASP.NET MVC 5. Attribute routing uses attributes to create Routes. Attribute routing gives you more control to handle URI by adding routes directly on the controller or action methods.

Attribute Routing should be registered in the RegisterRoutes method of Global.asax or in RouteConfig file. It should be configured before convention based routing.

Below code shows how to register Attribute Routing


public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
        //Add the following line of code
        routes.MapMvcAttributeRoutes(); 
 
        //convention based routes
    }
}
            

In case if you are using both Attribute routing and convention based routing, the actions which are configured for Attribute routing will work as per Attribute Routes and the actions which are not configured will work as convention based routes.

Below is an example of AttributeRouting specified for Controller Action methods

[Route(/home/)]
public class HomeController : Controller
{
       [Route("home/about")]
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached USERS/About route";
           return View();
       }
}
        

URL http://example.com/home/about will be handled by above action method.

You can also use routing with Controller. Below code shows how you can use AttributeRouting with Controller.

[RoutePrefix("AppHome")]
[Route("{action=index}")] 
    //default action used when URL action parameter is not exist in controller. 
    //e.g. http://example.com/apphome or http://example.com/apphome/details
public class HomeController : Controller
{
     //new route: /AppHome/Index 
     public ActionResult Index()
     {
        return View();
     }
 
     //new route: /AppHome/About 
     public ActionResult About()
     {
         ViewBag.Message = "Application About us page.";
         return View();
     }
 
     //new route: /AppHome/Contact 
     public ActionResult Contact()
     {
            ViewBag.Message = "Application contact us page."; 
            return View();
     }
}
        

Routing Constraints

Routing constraints allow you to use validation on defined routes. It enables you to prevent getting route maps with browser requests unless specific validation matched. For example, browser requests should be matched with specific routes only if the id parameter is type of int.

Below route definition creates Route with constraint that allows only integer value for id parameter.

routes.MapRoute("Default", // Route name
    "{controller}/{action}/{id}", // Route Pattern
    new { controller = "Orders", action = "GetOrder",
            id = UrlParameter.Optional }, // Default values for parameters
    new { id = @"\d+" } //Restriction for id
    );            
            

If you need more complex validation, you can implement the IRouteConstraint interface and use the Match method to implement logic.

The below code creates custom route constraints by implementing IRouteConstraint. Which checks whether the provided parameter is a valid date or not.


public class DateConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, 
        string parameterName, RouteValueDictionary values,
                 RouteDirection routeDirection)
    {
        DateTime dt;
 
        return DateTime.TryParseExact(values[parameterName].ToString(), 
        "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
    }
}
            

Add route with Constraint

    routes.MapRoute("sample", "{controller}/{action}/{reportdate}", null,
        new { reportdate = new DateConstraint() });
        

Catch-all Route

A catch-all parameter useful for a route to match part of a URL with an unpredictable number of segments. If any query string used, it excludes the URL. A catch-all parameter is allowed only for the last segment of the route template.

For example, the following traditional route created with catch-all parameter with * symbol.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapRoute("catchallroute", "blog/{blog-name}/{*extrastuff}",
            new { controller = "blog", action = "showblog"));
}
        

It handles below url

  • http://example.com/blog/how-to/2015/12/01
  • http://example.com/blog/abc/2015/12/
  • http://example.com/blog/abc/2015/
  • http://example.com/blog/xyz/
  • http://example.com/blog/xyz

Area Registration

The area is a feature of MVC2. It allows you to organize applications part in a better way. For example, you have a billing application you may have different parts like Billing, Admin, Order and so on. You will create different Areas for each part. Each area will contain Views, Controllers, and Models specific to the Area.

You can register specific area by inherting AreaRegistration class

Below code shows how to register Admin Area.


public class HelpDeskAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        { 
            return "Admin";
        }
    }
}
  
public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "admin_default",
        "admin/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}
            

See more details about ASP.NET MVC Area Registration

Speak your mind
Please login to post your comment!