Skip to main content
Logo

Getting URLs in components

Once we've defined our routes, we need to generate them when rendering content. On a Contensis published site, you can create a custom method to do this.

This method would be added to our Movies.Routing.cs file below where we've defined our routes.

public static string GetUrl(string contentType, dynamic parameters)
{
    Page page = new Page();
    string url = string.Empty;
    switch (contentType)
    {
        case "movie":
            url = page.GetRouteUrl("movie", new
            {
                genre = parameters.Genre,
                movie = parameters.Slug
            });
            break;
        case "person":
            url = page.GetRouteUrl("person", new
            {
                person = parameters.Slug
            });
            break;
    }
    return url;
}

We also need to add a reference to a namespace that contains the .NET Page class.

using System.Web.UI;

Now let's look at the code in more detail:

public static string GetUrl(string contentType, dynamic parameters = null)
{
    Page page = new Page();
    string url = string.Empty;
    switch (contentType) {
        //Code to generate URLs goes here
    }
}

Our method is called GetUrl and the parameters we'll need to pass in are the content type ID and a dynamic object that will contain the URL parameters. We then declare a new instance of standard .NET page class so we can use some built in routing methods later in our code Page page = new Page().

Then we declare a string variable that will be populated with the generated URL. string url = string.Empty;

Next we start a new switch state and base this on the content type. Each content type you are rendering content for will typically have its route and unique parameters. So we need to generate a different URL depending on the content type.

switch (contentType) {
    //Code to generate URLs goes here
 }

Now let's look at how we'd generate a URL for a movie:

case "movie":
    url = page.GetRouteUrl("movie", new
    {
        genre = parameters.Genre,
        movie = parameters.Slug
    });
    break;

By using the .NET GetRouteUrl method, we can load a route by passing in its name, in this case movie. Then we can set the route parameter values using information we've passed in from some code that is rendering movie data and return the correct URL.

If we assume we've defined our route like this:

 "movies/{genre}/{movie}"

And this is how are we calling the method in our code that's doing some rendering.

<ul>
    @foreach (Entry movie in movies.Items)
    {
        dynamic urlParameters = new
        {
            genre = movie.Get<TaxonomyNode>('genre').Name,
            movie = movie.Sys.Slug
        };

        <li>
            <a href="@Routing.GetUrl(movie.Sys.ContentTypeId,urlParameters)">
            </a>
        </li>
    }
</ul>

If we assume one of the entries returned has a title of Batman Begins and a genre of Action, the generated URL would look like this:

 "movies/action/batman-begins"

Our routing class would now look like this:

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

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 {
                {"movie", new MovieConstraint() } }
            );

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

        public static string GetUrl(string contentType, dynamic parameters)
        {
            Page page = new Page();
            string url = string.Empty;
            switch (contentType)
            {
                case "movie":
                    url = page.GetRouteUrl("movie", new
                    {
                        genre = parameters.Genre,
                        movie = parameters.Slug
                    });
                    break;
                case "person":
                    url = page.GetRouteUrl("people", new
                    {
                        person = parameters.Slug
                    });
                    break;
            }
            return url;
        }
    }
}