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:
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:
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:
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:
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:
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:
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!