Using routes to create a custom url shortener in your existing mvc site

less than a minute read

As part of my new blog i wanted to create my own url shortener. I also wanted the short url's to be based off the root of my site allowing the following as well as other controllers to still work as normal:

Url Structure

I still want to maintain routing to my controllers so the following urls must behave as normal

http://jnye.co/
http://jnye.co/Posts
http://jnye.co/Search

However the following url should also be supported (where '4N2VN7' can be replaced with any text)

http://jnye.co/4N2VN7

The Solution

The solution was fairly simple. First we have to create a route for each controller so they are not treated as short urls. I also needed to add an additional route to identify the url shortener. Below are the routes I added. Remember order is important when it comes to routes as they are checked in order and when one is matched the other routes are not required to be checked.

// Search controller
routes.MapRoute(
    name: "Search",
    url: "search/{action}/{id}",
    defaults: new {controller = "Search", action = "Index", id = UrlParameter.Optional}
);

//Posts controller
routes.MapRoute(
    name: "Posts",
    url: "posts/{action}/{id}",
    defaults: new { controller = "Posts", action = "Index", id = UrlParameter.Optional }
);

//Url shortener route
routes.MapRoute(
    name: "ShortUrl",
    url: "{shortUrl}",
    defaults: new { controller = "Home", action = "Index", shortUrl = UrlParameter.Optional }
);

//To catch http://jnye.co
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

In my Home controller I have the following code to match a short url against my database. If none is supplied or no match is found I return the home page:

// GET: /Home/
public ActionResult Index(string shortUrl)
{
    if (string.IsNullOrEmpty(shortUrl))
    {
        //Show home page
        return View();                
    }

    //Retrieve related post
    var redirectPost = GetPostByShortUrl(shortUrl);
    if(redirectPost == null)
    {
        //No match, serve home page
        return View();
    }
    
    //Redirect to relate post
    return RedirectToAction("Index", "Posts", new {area = "", id = redirectPost.Id});
}

...And that's it. Our very own custom url shortener. Please share using the sharing links above, which utilize the very url shortener I have implemented here ;-).