ASP.NET MVC QuickStart 5: routing

Objectives

In this Hands-On Lab, you will be introduced to the ASP.NET MVC framework. In particular, you will:

  • Task 1: Understand routing
  • Task 2: Add constraint
  • Task 3: Add new route
  • Task 4: Generate outgoing URL’s

System requirements

You must have the following items to complete this lab:

  • Microsoft Visual Studio 2008 SP1 (professional edition)
  • Microsoft ASP.NET MVC 1.0

Prequisites

You must have the following skills to understand this lab:

  • Fundamental knowledge of software development in .NET 3.5
  • Some experience in ASP.NET web development

This lab builds further on the QuickStart 4 code.

Task 1: understand routing

In ASP.NET MVC, a URL does not map to a file, but on an action method of a controller. This routing from URL to controller/action can be configured in the routing table, that is configured in the RegisterRoutes method of the Global.asax.cs file in the web application project, which defaults to:

  1: public static void RegisterRoutes(RouteCollection routes)
  2: {
  3:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  4:     routes.MapRoute(
  5:         "Default",                              // Route name
  6:         "{controller}/{action}/{id}",           // URL with parameters
  7:         new { controller = "Home",
  8:               action = "Index",
  9:               id = "" }                         // Parameter defaults
 10:     );
 11: }

Note: the routing system not only maps incoming URL’S to the appropriate controller/action, but also constructs outgoing URLS!

Each route defines an URL pattern and how to handle requests for such URL’s. For the default route, this means:

URL                                 Maps to
/                                   controller = Home, action = Index, id = “”
/members                            controller = Members, action = Index, id = “”
/members/create                     controller = Members, action = Create, id = “”
/members/details/2                  controller = Members, action = Details, id = “2”

If you omit controller in the URL, it defaults to Home because we specified a parameter default for controller. If you omit action in the URL, it defaults to Index because we specified a parameter default for action.

When you define a route by using the MapRoute method, you can pass a number of parameters:

  • a route name, which is optional
  • the URL pattern, using parameters
  • default values: default value for each parameter (optional)
  • constraints: constraints for each parameter (optional)

Task 2: Add constraint

If you use http://localhost:3382/members/Details/2 then it will map to the Details action method of the MembersController, and member with ID 2 will be shown. This works, because ‘2’ will be mapped to the id parameter of the Details action method.

However, http://localhost:3382/members/Details/a also matches the URL pattern “{controller}/{action}/{id}” and so ‘a’ will be mapped to the id parameter. But, id is of type int, and so you will get the error:

ASPNETMVC_QS5_01

Obviously, we know that id should be a valid number, but the routing system doesn’t know that. To solve this, we can add a constraint to be sure that the mapping is only done when id is a valid number:

  1: routes.MapRoute(
  2:       "Default",                          // Route name
  3:       "{controller}/{action}/{id}",       // URL with parameters
  4:       new { controller = "Home",
  5:             action = "Index",
  6:             id = 0 },                     // Parameter defaults
  7:       new { id = @"\d{1,6}" }             // Constraints
  8: );

Now, if id is not according to the regular expression ‘\d{1,6}’ (numeric, 1 to 6 digits long) then the rule does not match and  the URL http://localhost:3382/members/Details/a isn’t mapped:

ASPNETMVC_QS5_02

Task 3: Add new route

Suppose we want the following URL to work:

URL                          Maps to
/member1                     controller = Members, action = Details, id = “1”
/member3                     controller = Members, action = Details, id = “3”

If you try that, obviously it does not match any URL pattern yet, so you’ll get an error:

ASPNETMVC_QS5_03

To make this work, add a new route to the global.asax.cs file (it has to be the first one):

  1: public static void RegisterRoutes(RouteCollection routes)
  2: {
  3:     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  4:     routes.MapRoute(
  5:       "",                                  // Route name
  6:       "member{id}",                        // URL with parameters
  7:       new { controller = "Members",
  8:             action = "Details",
  9:             id = 0 },                      // Parameter defaults
 10:       new { id = @"\d{1,6}" }              // Constraints
 11:             );
 12:     routes.MapRoute(
 13:       "Default",                           // Route name
 14:       "{controller}/{action}/{id}",        // URL with parameters
 15:       new { controller = "Home",
 16:       action = "Index",
 17:      id = 0 },                             // Parameter defaults
 18:      new { id = @"\d{1,6}" }               // Constraints
 19:             );                      
 20: }

Note: add routes in the correct order: from most specific to least specific!

Now try http://localhost:3382/member3:

ASPNETMVC_QS5_04

Task 4: Generate outgoing URL’s

Generating hyperlinks should never be done hardcoded, always use the built in helper methods like Html.ActionLink because they use the routing system to correctly build the URL.

In previous examples we already used Html.ActionLink to construct the links to view, create, edit and delete members, for example:

  1: <%= Html.ActionLink("Details", "Details", new { id = item.ID })%>

This generated the links as follows:

ASPNETMVC_QS5_05

However, in task 3 we added a new route to view the details of a member, so that URL’s in the form of http://localhost:3382/member3 work. After adding this route, the generated URL’s look different:

ASPNETMVC_QS5_06

This is because Html.ActionLink uses the routing configuration to construct the URL’s.

Note: If we would have constructed the links hard coded, changing routing configuration may have broken those links!

May 7, 2010 02:01 by lustuyck
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed