Skip to main content
Logo

Defining routes

Each route will be added to the .NET RouteTable class so we use them within our application.

A fully defined set of routes might look something like this:

using System.Web.Mvc;
using System.Web.Routing;

namespace Movies.App
{
    public class Routing
    {
        public static void RegisterCustomRoutes(RouteCollection routes)
        {
            //Set behaviour and validation for all routes

            //Convert all paths to be lowercase in the context of this method
            routes.LowercaseUrls = true;

            //If the file exists on the server, still apply routing rules as opposed to simply returning the file straight from disk.
            routes.RouteExistingFiles = true;

            //Don't route any url that end in .aspx as these will be looking for a specific page
            //In effect, define an exception for routes.RouteExistingFiles = true
            routes.IgnoreRoute("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" });

            //Movies route
            routes.MapPageRoute(
                "movie",
                "movies/{genre}/{movie}",
                "~/movies/movie.aspx",
                false,
                null,
                new RouteValueDictionary
                {
                    {
                        "genre", @"[a-z]+(-[a-z]+)*$"
                    },
                    {
                        "movie", new MovieConstraint()
                    }
                }
            );

            //People route
            routes.MapPageRoute(
                "person",
                "people/{person}",
                "~/people/person.aspx",
                false,
                null,
                new RouteValueDictionary
                {
                    {
                        "person", new PersonConstraint()
                    }
                }
            );
        }
    }
}

This would typically sit in a file called Movies.Routing.cs in App_Code > CS

Routing file in Contensis

So let's go through the code in more detail:

using System.Web.Mvc;
using System.Web.Routing;

namespace Movies.App
{
    public class Routing
    {
        public static void RegisterCustomRoutes(RouteCollection routes)
        {
           //Define routes here
        }
    }
}

Here we're referencing the namespace of our app and defining a class and method that match with the code from the Routing in Contensis article.

//Set behaviour and validation for all routes

//Convert all paths to be lowercase in the context of this method
routes.LowercaseUrls = true;

//If the file exists on the server, still apply routing rules as opposed to simply returning the file straight from disk.
routes.RouteExistingFiles = true;

//Don't route any url that ends in .aspx as these will be looking for a specific page
//In effect, define an exception for routes.RouteExistingFiles = true
routes.IgnoreRoute("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" });

This section of code sets the default behaviour for how all requests are routed within the application.

This next block of code is where we define our route using the MapPageRoute method:

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx",
    false,
    null,
    new RouteValueDictionary
    {
        {
            "genre", @"[a-z]+(-[a-z]+)*$"
        },
        {
            "movie", new MovieConstraint()
        }
    }
);

The first parameter defines the name of our route, which must be unique across all routes in the route table. The second is the URL pattern for the route. This includes any dynamic parameters that will be different for each URL. These are defined using the {parameter} format. In the case of our movie route, {genre}/{movie} are the dynamic parameters. So one URL would be https://www.application.com/movies/adventure/passengers and another one might be https://www.application.com/movies/family/finding-dory. The third is the path to the physical file on disk that contains the code to render content.

For a Contensis site, this will typically be an .aspx page which contains a Razor View that renders the content.

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx"
);

The next parameter relates to the CheckPhysicalUrlAccess property. This is only set to true if the content is in a secure area of the application. This property relates to standard .NET authentication as opposed to Contensis authentication.

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx",
    false
);

The null value is where we would set any defaults for our route parameters.

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx",
    false,
    null
);

If our application supported multiple languages. Our main route might contain and additional language parameter:

"{lang}movies/{genre}/{movie}"

In this case, we might want to set a default/fallback to return the English version of the movie:

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx",
    false,
    new RouteValueDictionary
    {
        {
            "lang", "en-gb"
        }
    },
);

The final value we pass in is a set of constraints for our route parameters. These constraints define what conditions the relevant parameters of the URL must meet for the route to be valid. For our movie route, we are validating against the movie parameter only but we could also validate against the genre parameter.

//Movies route
routes.MapPageRoute(
    "movie",
    "movies/{genre}/{movie}",
    "~/movies/movie.aspx",
    false,
    null,
    new RouteValueDictionary
    {
        {
            "genre", @"[a-z]+(-[a-z]+)*$"
        },
        {
            "movie", new MovieConstraint()
        }
    }
);

Constraints can be simple regex validations but in our case, we are also targeting a MovieConstraint class that should return an entry that matches this route.

We can follow the same approach for our person route so we end up with the following code.

using System.Web.Mvc;
using System.Web.Routing;

namespace Movies.App
{
    public class Routing
    {
        public static void RegisterCustomRoutes(RouteCollection routes)
        {
            //Set behaviour and validation for all routes

            //Convert all paths to be lowercase in the context of this method
            routes.LowercaseUrls = true;

            //If the file exists on the server, still apply routing rules as opposed to simply returning the file straight from disk.
            routes.RouteExistingFiles = true;

            //Don't route any url that end in .aspx as these will be looking for a specific page
            //In effect, define an exception for routes.RouteExistingFiles = true
            routes.IgnoreRoute("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" });

            //Movies route
            routes.MapPageRoute(
                "movie",
                "movies/{genre}/{movie}",
                "~/movies/movie.aspx",
                false,
                null,
                new RouteValueDictionary
                {
                    {
                        "genre", @"[a-z]+(-[a-z]+)*$"
                    },
                    {
                        "movie", new MovieConstraint()
                    }
                }
            );

            //People route
            routes.MapPageRoute(
                "person",
                "people/{person}",
                "~/people/person.aspx",
                false,
                null,
                new RouteValueDictionary
                {
                    {
                        "person", new PersonConstraint()
                    }
                }
            );
        }
    }
}

If no entries are returned then the next route would be checked. If no routes and/or route constraints match the requested URL then a Contensis site will throw a 404 error.

Now you've defined your routes, the next step is to define your constraints. These will determine what content is returned by a particular route.