Skip to the content

Umbraco 9 Route hijacking | Custom RenderControllers | How and Why

What is Route hijacking in Umbraco 9?

Route hijacking is a technique I've loved for quite some time. A little bit of history..

When I started out with earlier versions on Umbraco I found that by the end of the project my Razor Views looked really messy and contained a lot of code. I didn't really like this kind of setup. It seemed Umbraco sort of took away controllers form the developer and all the main code always ended up within the razor views.

There were ways to clean this up such as moving code into static classes and importing the code in to the Razor View from there. I still didn't like this setup and kind of felt even though we were coding in MVC we were not really following the MVC pattern since the controllers were used for the Umbraco base code and tucked away from us devs.

I kind of persevered with this approach for a number of years since I just didn't have time to figure out a better approved. As I got used to Umbraco and gradually kept improving my code I came across what's know as 'Route Hijacking'.

So what is Route Hijacking I hear you say...

This is a way of 'Hijacking' the request and running it through your own controller before pushing everything to the view. This is a really handy technique if you have a lot of code relating to a page been requests. The page might have a load of Lucene searching doing on, it might be a blog article which has a load of related blog articles that's smartly assigned with some algorithm you created.

You obviously would prefer this code not to be all stored on the Razor View. Instead you can use 'Route Hijacking' to capture the request, add a number of properties on the view model (maybe your related blog articles) before pushing it back out to the View. This way your Razor View would be nice and clean, not containing any code other than your basic html and Razor script.

What's my usual setup and when do I use 'Route Hijacking'

I pretty much use 'Route Hijacking' for everything. Over time I moved away from the out of the box Umbraco rendering and ran everything through my custom controllers. I just found that it took a little longer to get set up at the beginning of a project but over time this massively speeded up the time I could code websites (by a hell of a lot).

What's my usual setup? 

1. I create a custom Render Model for each of my page types 'HomePageViewModel', 'ContentPageViewModel' etc.

2. I then cast the Umbraco Models Builder content to a Strongly Typed Model stored on my RenderModel

Eg. 

public HomePage StronglyTyped { get; set; }

This later allows me awesome use of Visual Studio intellisense throughout the whole project in my Razor Views.

@Model.StronglyTyped.MainText

3. All my custom Render Model inherit from a 'Base Render Model' I create.

4. Inside the 'Base Render Model' I have a load of properties that are commonly used across all pages. 

These might include...

  • Site Settings (reading from a doc type stored in Umbraco)
  • Site Settings (reading from application settings)
  • Meta Data
  • Common Navigation Settings (Social Media Links etc)
  • Commonly used Contact Details (Phone, Email etc)

This means I can surface site settings and common data to all pages without having to add any extra code to razor view like GetSiteSettings, GetSocialMediaLinks etc.

5. I then have a custom MVC render controller which captures the request, gets the incoming model from Umbraco, parses it to my custom model and then passed it out to the view. This controller is also a great place to add all your custom cs.net code like I mentioned above. Maybe you could add a new property to your HomePageViewModel called 'PopularBlogArticles' and have some code stored in your controller to handle the smarts around this.

 

How to 'Route Hijacking' with Umbraco 9

This changed somewhat to Umbraco 7 and 8. It is best I give you some code examples of some very simples models and controllers. I set up.

1. The Custom Render Model

If you ModelBuilder doc type is called HomePage then I like to call my custom render model HomePageViewModel. This must inherit from ContentModel. If you want to go down the same path as me and have a 'Base Render Model' then I will let you figure that out. That or drop me a message and I will show you some examples of my setup in more detail. The setup in my example is just the basics to get you up and running with Route Hijacking in Umbraco 9.

using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Web.Common.PublishedModels;

namespace Website.Core.Models
{
     public class HomePageViewModel : ContentModel
     {
           public HomePageViewModel(IPublishedContent content) : base(content) {
                 StronglyTyped = (HomePage)content;
           }
           public HomePage StronglyTyped { get; set; }
      }
}

2. The Custom MVC Render Controller

The trick here is it's important that your controller name is a match to your document type name. If it isn't then it simply wont catch (hijack) the request. So if your page doc type is 'HomePage' then the class name must be HomePageController. The second thing to note is this must inherit from RenderController. If you want to go down the path of having a base controller then I will let you also figure this out.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;
using Website.Core.Models;
namespace Website.Core.Controllers
{
      public class HomePageController : RenderController
      {
            public HomePageController(ILogger<HomePageController> logger, ICompositeViewEngine compositeViewEngine,
             IUmbracoContextAccessor umbracoContextAccessor) : base(logger, compositeViewEngine, umbracoContextAccessor)
            {
            }
            public override IActionResult Index()
            {
                   var vm = new HomePageViewModel(CurrentPage) { };
                   return View("/Views/homePage.cshtml", vm);
             }
      }
}

3. The frontend View Page Template (cs.html file)

Now all the backend stuff is finished there is one thing you need to do to your page template. You now need to make this inherit from your new 'HomePageViewModel'. Also when you are referencing properties stored on the doc type stored in Umbraco you will see that you have access to them through intellisense within Visual Studio under the @Model.StronglyTyped. property.

@inherits UmbracoViewPage<Website.Core.Models.HomePageViewModel>
@{
     Layout = "Master.cshtml";
}
<h1>Homepage</h1>
@if (!string.IsNullOrEmpty(Model.StronglyTyped.Heading))
{
     <h2>@Model.StronglyTyped.Heading</h2>
}

 

About the author

David Armitage

.Net MVC Developer
.Net Core Developer
Umbraco Certified Master
Recruitment Professional

Hey Peeps,

I'm an entrepreneur and web developer with a passion for coding. I absolutely love working with Umbraco CMS and appreciate the Umbraco community even more.

I've got 10 years+ .Net experience and 7 years+ experience working in the recruitment industry, both coding and marketing job websites. I wanted to use my skills to help give something back to this awesome community and so I decided to build UmbraJobs.com.

My vision & fundamentals

I want this website to be a place where Umbraco Professionals and Umbraco Partners can advertise their services but at the same time I want to filter out all the under-qualified freelancers & agencies that take up the biggest part of other job & freelancer websites. We've all worked hard to gain our Umbraco certifications, partnership status, and help build the Umbraco community to what it is today. I want to see everyone get rewarded for their efforts.

Follow me on social media

If you're an Umbraco professional, partner, employer, recruiter or a passionate Umbraco community builder then I'm more than happy to hear from you. Follow me on my social media channels and please reach out if you have any needs, want help or consultation with anything Umbraco related or just want a general chat.

comments powered by Disqus

Blog Filter


How we can help?

Need help with an Umbraco project?

Need help with a project but not too sure who to approach? Send us your project brief and budget. We will provide a free consultation and can help you gather quotes from the best and most suitable freelancers or agencies.

Looking to hire an Umbraco Professional?

Have you got job vacancy and want to hire an Umbraco professional? Post a job on our website for free. Alternatively let us know your requirements and we will send suitable prospects your way.

Claim your free profile!

Are you an Umbraco Freelance Developer or Umbraco partner that wants to advertise on our site? If you work with Umbraco or registered as an Umbraco partner then you can create a profile for free.

Let's build the Umbraco Community

We're big on building the Umbraco community and we think you guys are awesome! If there's anyway at all we can help then please reach out.