ASP.NET MVC Routing – StopRoutingHandler and IgnoreRoute

There are two methods to exclude a URL from being handled by Routing – StopRoutingHandler and IgnoreRoute.

StopRoutingHandler

The below listing shows two routes created manually, the first of which has a StopRoutingHandler which blocks Routing for handling the matching URL:

public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(new Route
(
"{appresource}.axd/{*urlInfo}", new StopRoutingHandler() ));

routes.Add(new Route
(
"articles/{cat}/{id}", new SomeRouteHandler()  ));
}

Therefore a URL such as resource1.axd will be matched to the first route and since that route returns a StopRoutingHandler  Routing system will pass this request on for normal ASP.NET processing.

IgnoreRoute

A simpler way to circumvent Routing is to use IgnoreRoute .

This is declared in a similar manner to the familiar MapRoute method and is normally used alongside it as shown below:

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(“{appresource}.axd/{*urlInfo}“);
routes.MapRoute("norm", “articles/{cat}/{id}“, new MvcRouteHandler());
}

This is a lot tidier than the method using StopRoutingHandler and functions exactly the same.

ASP.NET MVC Routing – WildCard Parameters

A wildcard or catch-all parameter in MVC Routing allows for a route to match a URL with an arbitrary number of parameters. This feature is especially useful when building CMSs, blogs, wikis and other content driven applications.

Typically, URLs for such content driven apps should be as descriptive as possible, for example reviews/hotels/germany/berlin/fourseasons. But what if the CMS also handles airline reviews, and want to use URLs like reviews/airlines/northwest . In this circumstance reviews would be the controller and airlines or hotels the action, but the id is either germany/berlin/fourseasons or northwest. Normally the parameters are inferred from the “/” character, but with wildcard parameters a chunk of a URL with multiple / characters can be read as a single parameter. In this case the below route definition could be used:

routes.MapRoute("reviews", "{controller}/{action}/{*id}");

The WildCard * character allows everything beyond the action parameter to be placed in the id parameter.

ASP.NET MVC Routing – Constraints

MVC Routing Constraints allow for the application of a regular expression to a URL segment to determine if the route will match the request.

Previously in the introductory MVC Routing Tutorial we looked at defining Routes based on the number of segments in a URL. So the Route definition:

routes.MapRoute(“simple”, “{controller}/{action}/{id}“);

would match the URL /articles/category/12 . But suppose the content management system we are building also had a blog and we wanted to use URLs such as /2010/04/03. Such a URL would map to the simple Route we defined above and so in our example it would be processed as if it were referring to an article category.

Therefore we can see that just mapping URL segments to Route definitions is extremely limiting. Constraints allow for regex to be used to read the contents of the URL parameters to determine which Route definition to use. For example:

routes.MapRoute(“blogpost”, “{year}/{month}/{day}“
, new {controller=”blogpost”, action=”index”}
, new {year=@“\d{4}“, month=@“\d{2}“, day=@“\d{2}“});

routes.MapRoute(“simple”, “{controller}/{action}/{id}“);

Here there are two route definitions both of which have three parameters. Note the highlighted part of the blogpost route definition which is the definition of the constraint. The constraint in this case matches a URL of  4 digit number/2 digit number/2 digit number format. If this test is met the blogpost route definition will be applied, for all other 3 segment URLs the simple route definition will be applied.

Note the order of the definitions. ASP.NET MVC Routing attempts to match route definitions in sequence and once a match is made it is processed. Therefore, routes which contain constraints should always be placed before the simple non-constrained route definitions.

ASP.NET MVC Routing – Multiple Parameters

In MVC Routing, multiple parameters can be used in a URL segment. For example the route definition:

routes.MapRoute(“multiple”, “{controller}/{action}/{author}-{tag}");

contains multiple parameters (ie author and id) in the final segment. This will match the URL blog/technology/johnspencer-aspnet . Any literal string can separate the multiple parameters, so the route definitions {author}.{tag} , {author}on{tag}, author-{author}on{tag} are all be valid. The parameters must be separated by a literal string, so the definition {author}{tag} would not be valid.

When working with multiple parameters it is important to understand the concept of greedy matching. Under this concept the first parameter will take the maximum amount of the url fragment that is possible. For example, how would the URL fragment /john.francis.spencer.sqlserver/ be mapped the the route definition {author}.{tag} since the are three “.” characters and only one as a literal in the route definition? Under greedy matching, the first parameter (author) will take john.francis.spencer but leave sqlserver for the tag parameter since the tag parameter must take at least some text beyond a “.” character.  

ASP.NET MVC Routing – Default Values

Default values in ASP.NET MVC Routing allow for much more flexible URL pattern matching. In our previous   MVC Routing Tutorial we introduced Routing and how it matches a URL to a predefined Route and then extracts the parameters for processing. In our original simple examples, a URL segment had to be provided for each parameter in a URL Route.

So, to recap, if we defined a URL Route for handling incoming URLs for a content  management system  which needs to display the articles for a given category then the route may look as below:

routes.MapRoute(“simple”, “{controller}/{action}/{id}“);

and the URL of /articles/category/15 would result in the below controller (with 15 being passed in as the id parameter).

public class ArticlesController : Controller
{
public ActionResult Category(int id)
{
//Perform Operations....
}
}

This url would therefore  output the articles for Category ID 15. But what if we wanted to use the URL /articles/category/ to display all the articles irrespective of category. For this we would need to use default values in Routing.

The provision of a default value in the Route definition allows ASP.NET MVC Routing to provide a preset value when none is provided in the URL (in a  similar fashion to default values for parameters in function definitions).

The default value needs to be in the Route definition:

routes.MapRoute(“simple”, “{controller}/{action}/{id}“, new {id = 0});

Now, the URL /articles/category/ will be interpretted as /articles/category/0 and so in this example the 0 value for id can be used to display all articles regardless of category.

Multiple Default Values

Multiple default values can be used for different parameters as shown below:

routes.MapRoute(“simple” , “{controller}/{action}/{id}“,
new {id = 0, action=”home”});

In this example the URL /articles/category/ would behave as shown previously but the URL /articles/ would behave as /articles/home/ ( and so in the example of a content management system the URL /articles/category/ would be the articles home page).

One rule to bear in mind when using default values is the if a default is defined for a parameter then all subsequent parameters must have a default value as well. For example :

routes.MapRoute(“simple” , “{controller}/{action}/{id}“,
new { action=”home”});

is not valid and a default for the id parameter needs to be assigned.

Another caveat in using default values is that defaults cannot be used when literal values are used in parameters. For example the Route,

routes.MapRoute(“simple” , “{controller}/{action}-{id}”);

uses the literal string “  - ” to separate {controller} and {action} which would match URLs such as /articles/category-12/ . In this case a default cannot be used for action or id .

ASP.NET MVC Routing Tutorial – Part I

In this tutorial we will take a look at ASP.NET MVC Routing which is a very powerful method of handling URL’s in web apps. It should be noted at the outset that R0uting is not exclusive to MVC and can also be used in ASP.NET 4.0 – see ASP.NET 4.0 URL Routing Tutorial for more details (most of the detail provided below is applicable to ASP.NET Routing as well as MVC Routing,  although the implementation is slightly different)

ASP.NET MVC Routing serves two main purposes:

  • Matching incoming requests and mapping them to a controller action.
  • Constructing outgoing URLs which correspond to controller actions.

ASP.NET MVC Routing compared to URL Rewriting

Both Routing and URL ReWriting can create search engine friendly  URLs. A key difference, however, is that URL Rewriting is an approach which focuses on a single page at a time. Most ASP.NET URL rewriting schemes rewrite a URL for one page to be handled by another. For example ,  /product/cars.aspx might be rewritten as: /products.aspx?id=65 .

Routing, by contrast. is a resource-centric view of URLs. A URL represents a resource which is not necessarily a web page. With Routing, this resource is a block of code that executes when an incoming request matches the route. A route determines how a request is dispatched based on characteristics of a URL.

Another difference is that Routing is bidirectional as it also helps in generating  URLs by using the same rules used to match incoming URLs. However, ASP.NET Routing never actually rewrites a URL, the URL that a user requests in the browser is the same URL the application sees throughout the request lifecycle.

Defining Routes

An ASP.NET MVC app needs a minimum of one route to define how the app should handle requests, complex apps will likely have numerous routes.  Route definitions begin with a URL that specifies a pattern the route will match. As well as the route URL, routes may also specify a default value and constraints for parts of the URL. This provides very tight control over how a route matches the incoming request URLs.

Route URLs

In the Application_Start method of the Global.asax.cs file in a ASP.NET MVC Web Application project, there is a call to the RegisterRoutes method. This method is the place where all the routes for the app are registered.

For this tutorial we can remove all the routes in there  and enter a single very simple route:
Continues…