Creating “Short” Urls in ASP.NET MVC

I recently created a site to promote small local coffee shops (LocalCoffee.Rocks). Each coffee shop location has its own profile page. I wanted to make it easy for these shops to point people directly to this dynamic page without having to give them an ugly url containing domain/controller/action/parameterId. I figured out a way to short circut the routing information using the Application_BeginRequest() method in the Global.asax file.

First, in the database, under each shop locations record I have a varchar(20) field for their “shortUrl”. This the string that shops can promote to their clients to go directly to their profile. For example instead of accessing users can simply enter to get to the same profile.

Once I had the value set in the db in the Application_BeginRequest() method to get the “controller” parameter from the url. The trick is that I do have other actual controllers that I want to fire and act just like they are designed in MVC. Thus, after I get the controller parameter I created a list and populated it with all of the names of the real controllers that are in the application. I did this with using reflection by calling the GetTypes() method from the Assembly class. After I had both the passed controller parameter and the list of physical controllers I simply check to see if the passed controller was in the list of physical controllers. If so I did nothing and the site continued to process as normal. If, however, the passed controller was not in the list it most likely is a shortUrl for a shop and so I passed that value to a function to handle that request. Below is the Application_BeginRequest() method.

        protected void Application_BeginRequest()
            //get current url
            HttpContextBase context = new HttpContextWrapper(HttpContext.Current);
            //break url up into routing sections(controller, actionresult, parameters)
            RouteData rd = RouteTable.Routes.GetRouteData(context);
            //get "controller" from route parameters
            string shortUrl = rd.GetRequiredString("controller").ToLower();

            //create list to store
            List<string> controllers = new List<string>();

            // Get list of all physical controllers in the application
            Assembly asm = Assembly.GetExecutingAssembly();
            var controllerNames = asm.GetTypes()
                .Where(type => typeof(Controller).IsAssignableFrom(type)).Select(t => t.Name.ToLower());

            // Add each controller to the controller list
            foreach (var item in controllerNames)
                string nameOnly = item.Substring(0, item.Length - 10);

            //check if controller is not in the list and if not pass it to the shortUrl processing method
            if (!controllers.Contains(shortUrl))
                //send shortUrl to method to get actual URL

In the shortUrl processing method I query the database for the passed value which should be located in the ShortUrl column of the database table for each shop location. Then, if a location was found I redirected the browser to the profile page using the full controller/action/parameterId url. If a location was not found the user could have mistyped the short url so I simply redirect them to a UrlNotFound page as seen below.

private void R(string ctrl)
            // Query DB for the controller name passed in
            UnitOfWork uow = new UnitOfWork(new ApplicationDbContext());
            Location location = uow.LocationRepository.Get().Where(x => x.Shop.IsActive == true && x.ShortUrl == ctrl.ToLower()).FirstOrDefault();

            // If a URL is found the controller name was a short url
            if (location != null)
                // Redirect to the actual website
                Response.Redirect("" + location.LocationId);

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *