Using Custom Routes in Umbraco

So if you come from a .Net MVC background and you’re building an Umbraco project, one of the first things you’re going to want to do is add your own custom routes. You create your custom controller and add your custom route into the RouteConfig.cs file and hit F5. Then you get an error saying that the route you just added can’t be found and you start to doubt everything you thought you knew (again).

This is because Umbraco hijacks the routing process of your once-familiar MVC project and puts its own routing engine in place! To add custom routing back in to your Umbraco project you have to do a bit of tinkering under the bonnet (like the bonnet of a car, not a bonnet you wear on your head).

I recently used my own controller and custom route on a project when I wanted to make AJAX calls from the site back to the server. I followed the instructions in the Umbraco documentation which got me 95% of the way, but there were a couple of gotchas. So here’s how you do it, gotchas included!

Step 1 – Set up your controller. This is the bit you already know and love – no change here. For my project the actions I added to my controller were JsonResult actions, as I was using Ajax, but you can use any controller actions. Here’s the basic code from my controller:

public class AjaxController : Controller
  {
    [HttpPost]
    public JsonResult OpinionPollPost(OpinionPollModel model)
    {
      RegisterVote(model, Response);

      var modelToReturn = GeneratePoll(model.Id, Request, model.Token);

      return Json(modelToReturn);
    }
  }

Step 2. Add the controller path to umbracoReservedPaths appSettings key in your web.config file. Any path added to this list will be ignored by Umbraco’s routing engine. My controller was called AjaxController, so I added “~/ajax/” to the umbracoReservedPaths list:

<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/ajax/" />

Step 3. Change your global.asax.cs to inherit from UmbracoApplication. Open up your global.asax.cs file and change this line:

public class MvcApplication : System.Web.HttpApplication

to this:

public class MvcApplication : UmbracoApplication

Step 4. Change your global.asax to inherit from your application. This was the big gotcha that caught me out and I had to do quite a bit of searching to find it! Open up your Global.asax file (right click on it and “View Markup”) and change this line:

<%@ Application Codebehind="Global.asax.cs" Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %>

to this:

<%@ Application Codebehind="Global.asax.cs" Inherits="MyProject.MvcApplication" Language="C#" %>

where “MyProject” in this example is the base namespace of your project.

Step 5. Remove the default custom route from RouteConfig.cs – this is another gotcha! If you don’t remove this route, MVC will try and route every request and your website will show en empty page which may be a nice clean design, but not very functional!

Step 6. Register your custom route in the RegisterRoutes method of your RouteConfig.cs. You have to do this for each route you want use:

routes.MapRoute(
  name: "Ajax",
  url: "Ajax/OpinionPollPost",
  defaults: new { controller = "Ajax", action = "OpinionPollPost" }
);

Step 7. Finally you need to add an OnApplicationStarted override method to global.asax.cs. This will allow you to add your application to read the RegisterRoutes method in your RouteConfig.cs file when it starts, and add the custom route you just set up into your application:

protected override void OnApplicationStarted(object sender, EventArgs e)
  {
    base.OnApplicationStarted(sender, e);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
  }

Now you just need to build and run your application, and you will be able to access your custom routes and controllers and make even more awesome Umbraco websites!

Posted in Code, MVC, Umbraco Tagged with: , ,
  • jake williamson

    mr. maff, was just trying this out on a project – works a treat!

    was also just looking at this:

    https://our.umbraco.org/documentation/Reference/WebApi/

    possible alternative meaning you don’t have to set up routes?

  • Hi Jake – thanks for the comment and I’m glad it helped you out! 🙂

    Yes the Umbraco Web API would also work in this scenario and wouldn’t require any custom routes like you said, so worth having both options in your Umbraco toolbox!

  • Pesy

    Cannot bind source type projectname.Models.OrderVM to model type Umbraco.Web.Models.RenderModel.

    • Hi Pesy,

      Sounds like you need to change the model in your template to use OrderVM.

      Thanks,

      Maff

      • Pesy

        Thanks for the reply Maff.
        How do i call Custom models and base controller in umbraco Template page?
        Kindly share if you are having a solution

        • Hi Pesy,

          If you post your question to the Umbraco forum with code examples you will be sure to receive help from there:

          https://our.umbraco.org/forum/

          Thanks,

          Maff

          • Pesy

            Thanks Maff for the suggestion

  • Hey do you have solution for this querry “Cannot find the Umbraco route definition in the route values when using custom Routes”

    I have experiencing an error when using custom routes.
    I have the below custom route:
    public class CustomRoutesApplicationEventHandler : ApplicationEventHandler
    {
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
    RouteTable.Routes.MapUmbracoRoute(
    ConstantValues.ProductsSearchCustomRouteName,
    “search/{” + ConstantValues.ProductsCategoriesRouteParamName + “}/”,
    new
    {
    controller = “Products”,
    action = “Products”
    },
    new UmbracoVirtualNodeByIdRouteHandler(ConstantValues.ProductsPageId)
    );

    }
    }
    When I get the full url for the route url and acutally redirect to that url, I am getting the below error:
    Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.InvalidOperationException: Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request
    Can anyone give me some insight about this?
    Thank you in advance.

About Maff

Maff Rigby

I'm a certified .Net, Umbraco and AngularJS freelance developer with over 15 years experience in the IT industry. As well as writing code I love to teach; I run a number of workshops and 1-1 coaching sessions on Angular JS and Umbraco, and share what I know and learn here!

I’m social (ish)

Connect with me on LinkedIn, follow me on Twitter, or fail to find me on Facebook.