Posted by: Cirilo Meggiolaro | 04/12/2009

Tip of the day #180 – ASP.NET MVC – Routing

Moving on the ASP.NET MVC series let’s check how the ASP.NET MVC routing works. If you have created or seen a ASP.NET MVC application you may have noticed the format of the URL:

http://localhost:4778/Account/Register

While the regular ASP.NET applications are based on folders and file names with an extension such as .aspx, the new routing model is based on an action stored in a controller class.

On the previous example “Register” is the name of an action, a public method exposed on a controller class called “Account”.

One important point is that ASP.NET MVC enforces some naming conventions to be followed on classes and some folders. All controller classes must have the Controller suffix on its name. So, in this case a class named AccountsController will be invoked. We are going to explore the Controller class in details during this week.

The main responsibility of the routing is to make this mapping between a request and an action and controller classes.

Web Config Setup

In the web.config the following sections allow you to set properties for routing:

  • system.web.httpModules;
  • system.web.httpHandlers;
  • system.webserver.modules;
  • system.webserver.handlers.

Global asax Setup

The most important component is the route collection. When an application starts a collection containing the rules to handle routing is registered and from that point on those rules are going to be parsed every time a request is made. This is done using the Global.asax file. To start create an ASP.NET MVC application using Visual Studio. As soon as it’s created, open the Global.asax file.

The file contains the Application_Start event and a method called RegisterRoutes responsible for route mapping. The default code is shown below:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

    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);
}

Basically when an application first starts, a route with the format Controller class / Action name / Id is registered. A default URL is also registered so requests in a format other than the one specified will make the action Index from the HomeController class to be invoked. You may change that.

Imagine a page that displays the details of a product with id equals to 123. The URL will be similar to the following: Product/Details/123. The application will try to map the request to a public method called Details stored in the ProductController class and that accepts an integer parameter. If an action with this name on this controller does not exist or if the controller does not exist, a 404 http error will occur.

Based on the defaults settings let’s simulate some requests. Assuming we have the following actions defined on a controller called ProductController and a view for each action:

public ActionResult Index()
{
    ViewData[“message”] = “Index method has been called.”;
    return View();
}

public ActionResult Details(int id)
{
    ViewData[“message”] = string.Format(“Details method has been called with the following id {0}.”, id);
    return View();
}

Check the outputs for some requests:

  • http://localhost:4778/Product/Details/123 – Action Details is invoked;
  • http://localhost:4778/Product/Details – An empty id will generate an ArgumentException since the Details action expects an integer. If the parameter is not mandatory, change the parameter to be a nullable type;
  • http://localhost:4778/Product – The Index action on the ProductController class will be invoked. If the Index action is not defined a 404 http error is thrown;
  • http://localhost:4778/ – The Index action on the HomeController class is invoked. That is the controller and action we defined on Global.asax file to be the default values for requests without specification.

Custom Routes

Imagine your application has a view that displays a list of products and you may want to pass an integer that represents the page number so you can implement paging to this view. You would have a URL similar to the following:

http://localhost:4778/Product/1

You may have noticed that the previous URL uses a different format than the one specified on Global.asax file. The URL above expects a controller class named Product and an integer is passed as parameter. The good news is that you may define your custom routes as you need. To achieve that you may add the code snippet below to the RegisterRoutes() method in the Global.asax file:

routes.MapRoute(“ProductList”, “Product/{page}”, new { controller = “Product”, action = “Index” });

On the code above:

  • We created a custom route named ProductList;
  • We defined the format: Product/page parameter;
  • A map to a controller class and an action was defined.

So if you request the URL the Index action will “intercept” and execute.

Constraints

You may enforce constraints using regular expressions and an overload of the MapRoute method. Using the same url: http://localhost:4778/Product/1. If you want to enforce that only numbers are passed as parameter, you may change the MapRoute call to the following:

routes.MapRoute(“ProductList”, “Product/{page}”, new { controller = “Product”, action = “Index” }, new { page = @”\d+” });

Now you have a constraint for your route. If you pass a different type than numbers to define the page parameter, an http 404 error will be thrown.

On the next post, let’s check what Controller classes are and how to work with.

Stay tuned!


Responses

  1. thanks

  2. Really your Tips for MVP are very much helpful and easy to undestand, KIndly keep posted on this as this will really help to the developers such as me who will get such a nice blog after so much googling on MVC.


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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Categories

%d bloggers like this: