Lab 7 - Introduction to Routing - 010515 Rev Ari

10
MODULE 7 STRUCTURING ASP.NET MVC 4 WEB APPLICATIONS LAB 7 – INTRODUCTION TO ROUTING Estimated time to complete this lab: 30 minutes Every ASP.NET MVC application needs routes to allow it to handle requests. Routes are the entry points into your MVC application. This section describes how to defi ne routes and discusses how they map requests to executable code, starting with the simplest kind of routes, called attributeroutes, which are new in ASP.NET MVC 5. After that, the discussion turns to the traditional routes that have been available since ASP.NET MVC 1. Routing within the ASP.NET MVC framework serves two main purposes: - It matches incoming requests that would not otherwise match a file on the file system and it maps the requests to a controller action. - It constructs outgoing URLs that correspond to controller actions. The preceding two items describe only what Routing does in the context of an ASP.NET MVC application. In this lab you will dig deeper and uncover additional Routing features available for ASP.NET. Lab Objectives After completing this lab, you will be able to: Define attribute routes Define routes values Define controller routes Test only the code you write Test validators kurang Introduction to Routing 7-1

description

aaa

Transcript of Lab 7 - Introduction to Routing - 010515 Rev Ari

MODULE 2

Module 7Structuring ASP.NET MVC 4 Web Applications Lab 7 Introduction to RoutingEstimated time to complete this lab: 30 minutes

Every ASP.NET MVC application needs routes to allow it to handle requests. Routes are the entry points into your MVC application. This section describes how to defi ne routes and discusses how they map requests to executable code, starting with the simplest kind of routes, called attributeroutes, which are new in ASP.NET MVC 5. After that, the discussion turns to the traditional routes that have been available since ASP.NET MVC 1.

Routing within the ASP.NET MVC framework serves two main purposes:

It matches incoming requests that would not otherwise match a file on the file system and it maps the requests to a controller action.

It constructs outgoing URLs that correspond to controller actions.

The preceding two items describe only what Routing does in the context of an ASP.NET MVC application. In this lab you will dig deeper and uncover additional Routing features available for ASP.NET. Lab Objectives

After completing this lab, you will be able to:

Define attribute routes Define routes values Define controller routes Test only the code you write Test validators kurangLab Procedures

A. Defining Attribute Routes Before you start looking at the details, heres a quick overview of the major concepts involved in defining attribute routes. A route definition starts with a URL template, which specifies the pattern that the route will match. Route definitions can appear as attributes on either the controller class or on an action method. Routes can also specify constraints and default values for the various parts of the URL, providing tight control over how and when the route matches incoming request URLs.Routes can even have names associated with them, which comes into play for outgoing URL construction (the second main purpose of Routing). Well cover named routes a bit later. Follow these steps to start with an extremely simple route and build up from there: 1. Make sure the project from the previous lab is open in your Solution Explorer.

2. Search and click Global.asax.cs from the Solution Explorer.

3. Youll notice that the Application_Start method contains a call to the RegisterRoutes method.

This method is the central control point for your routes and is located in the ~/App_Start/RouteConfig.cs file. Because youre starting with attribute routes, youll clear out everything in the RegisterRoutes method for now and just have it enable attribute routing by calling the MapMvcAttributeRoutes registration method.4. When youre done, your RegisterRoutes method should look like this: public static void RegisterRoutes(RouteCollection routes)

{

routes.MapMvcAttributeRoutes();

}

Now youre ready to write your first route.5. At its core, a routes job is to map a request to an action. The easiest way to do this is using an attribute directly on an action method:

public class HomeController : Controller

{

[Route("about")]

public ActionResult About()

{

return View();

}

}

This route attribute will run your About method any time a request comes in with /about as the URL. You tell MVC which URL youre using, and MVC runs your code. It doesnt get much simpler than this.6. If you have more than one URL for your action, you use multiple route attributes. For example, you might want your home page to be accessible through the URLs /, /home, and /home/index. Those routes would look like this:

[Route("")]

[Route("home")]

[Route("home/index")]

public ActionResult Index()

{

return View();

}B. Defining Routes ValuesThe static routes you saw earlier are great for the simplest routes, but not every URL is static. For example, if your action shows the details for a person record, you might want to include the record ID in your URL.Follow these steps to define the routes values by adding a route parameter:

1. Putting curly braces around id creates a placeholder for some text that you want to reference by name later.[Route("person/{id}")]

public ActionResult Details(int id)

{

// Do some work

return View();

}2. To be precise, youre capturing a path segment, which is one of part of a URL path separated by slashes (but not including the slashes). To see how that works, lets define a route like this:

[Route("{year}/{month}/{day}")]

public ActionResult Index(string year, string month, string day)

{

// Do some work

return View();

}3. Open your browser and invoke the index page with the following URL:

http://localhost/MVCMusicStore/index/2014/April/104. In the preceding method, the attribute route will match any URL with three segments because a route parameter, by default, matches any nonempty value. When this route matches a URL with three segments, so:

a. The text in the first segment of that URL (2014) corresponds to the {year} route parameter,

b. The value in the second segment of that URL (April) corresponds to the {month} route parameter, and c. The value in the third segment (10) corresponds to the {day} parameter.C. Defining Controller Routes So far, youve seen how to put route attributes directly on your action methods. But often, the methods in your controller class will follow a pattern with similar route templates. Follow these steps to define your custom controller routes:1. Consider the routes for a simple HomeController such as the one in a new MVC application:

public class HomeController : Controller

{

[Route("home/index")]

public ActionResult Index()

{

return View();

}

[Route("home/about")]

public ActionResult About()

{

return View();

}

[Route("home/contact")]

public ActionResult Contact()

{

return View();

}

}2. Change the above script with the following script to allow user invoke each action method on maps to a URL under home?.

[Route("home/{action}")]

public class HomeController : Controller

{

public ActionResult Index()

{

return View();

}

public ActionResult About()

{

return View();

}

public ActionResult Contact()

{

return View();

}

}Weve removed all the route attributes above each method and replaced them with one attribute on the controller class. When you define a route on the controller class, you can use a special route parameter named action, and it serves as a placeholder for any action name. It has the same effect as your putting separate routes on each action and typing in the action name statically.

3. Change the above script with the following script to allow user invoke each action index method on maps to /home/index or /home:

[Route("home/{action}")]

public class HomeController : Controller

{

[Route("home")]

[Route("home/index")]

public ActionResult Index()

{

return View();

}

public ActionResult About()

{

return View();

}

public ActionResult Contact()

{

return View();

}

}When you specify a route attribute at the action level, youre overriding anything specified at the controller level. In the preceding example, if the Index method only had the first route attribute (for home), it would not be accessible via home/index even though the controller has a default route for home/{action}. If youre customizing the routes for an action and you do want the default controller routes to apply, just list them again on your action.

4. The earlier class is still slightly repetitive. Every route begins with home/ (the class is named HomeController, after all). You can say that just once, using RoutePrefix:[RoutePrefix("home")]

[Route("{action}")]

public class HomeController : Controller

{

[Route("")]

[Route("index")]

public ActionResult Index()

{

return View();

}

public ActionResult About()

{

return View();

}

public ActionResult Contact()

{

return View();

}

}Now, all your route attributes can omit home/ because the prefi x provides that automatically.5. To make home controller support the URL / in addition to /home and /home/index enter the following script:

[RoutePrefix("home")]

[Route("{action}")]

public class HomeController : Controller

{

[Route("~/")]

[Route("")] // You can shorten this to [Route]

//if you prefer.

[Route("index")]

public ActionResult Index()

{

return View();

}

public ActionResult About()

{

return View();

}

public ActionResult Contact()

{

return View();

}

}

D. Defining Routes ConstraintsBecause your method parameter names are located right below your route attribute with its route parameter names, overlooking the differences between the two kinds of parameters can be easy to do. But when youre debugging, understanding the difference between a route parameter and a method parameter can be important. Follow these steps to define the route constraints:

1. Recall the earlier example with a record ID:[Route("person/{id}")]

public ActionResult Details(int id)

{

// Do some work

return View();

}For this route, think about what happens when a request comes in for the URL /person/bob. Whats the value of id? Well, thats a trick question: The answer depends on which id youre talking about, the route parameter or the action method parameter. As you saw earlier, a route parameter in a route will match any non-empty value. So, in Routing, the value of the route parameter id is bob, and the route matches. But later, when MVC tries to run the action, it sees that the action method declares its id method parameter to be an int, and the value bob from the Routing route parameter cant be converted to an int. So the method cant execute (and you never get to the point where there would be a value for id as a method parameter).2. If you wanted to support both /person/bob and /person/1 and run different actions for each URL? You might try to add a method overload with a different attribute route like this:

[Route("person/{id}")]

public ActionResult Details(int id)

{

// Do some work

return View();

}

[Route("person/{name}")]

public ActionResult Details(string name)

{

// Do some work

return View();

}If you look at the routes closely, youll realize theres a problem. One route uses a parameter called id and the other uses a parameter called name. It might seem obvious to you that name should be a string and name should be a number, but to Routing theyre both just route parameters, and, as youve seen, route parameters will match any string by default. So both routes match /person/bob and /person/1.4Introduction to Routing 7-1