In this tutorial, you will learn how to create and associate a controller with an Umbraco document type. This guide will cover all the code required to create your own MVC controller and intercept a page request. In Umbaco talk, this is known as route hijacking. This is one of the most important steps to learn in order to build web pages within the CMS, so carry on reading to learn more 🔥🔥🔥

Why Use A Controller?

Out-of-the-box, Umbraco does not force you into using a controller with your document types. It is possible to render views directly in Umbraco. Doing this means you are not using MVC in your project, you would be skipping the M and C part. MVC is by far the most used pattern to render web pages for a reason. Its used by millions as it leads to clean easy to understand code. Controllers allow you to do things like avoiding writing code in your view, talking to a business layer to get additional data for a page, as well as unit test your code.

Document Types

In order to render a page in Umbraco, you will be working with document types. If you are new to document types you can learn more about document types here). You will create one controller for each document type. The name of the controller needs to map to the document type alias.

You can find the document types Alias within the CMS:

How To Add Your Own Controller and View Model In Umbraco 1

When you create a new MVC project the installation wizard should have created a Controllers folder within the webroot. You can create your new controller here, however, I personally like to keep all my C# code in a separate code library. I cover for the reasons for this here

Creating a controller is simply a case of creating a new class. In a normal MVC application, a controller inherits from Controller. The name of the controller is related to the routing rules. In Umbraco, this is not the case. Controllers map to document types and controller inherits from RenderMvcController instead. The code to create a controller looks like this:

In this example, my document type alias is umbHomePage so my class would be called umbHomePageController. Notice how the code inherits from RenderMvcController. If you added this code to your project, when someone requested a page that was created using umbHomePage, the request pipeline will call this controller and hand execution over to the Index action by default. It is within this method you can your custom logic.

What If I Have Multiple Templates Associated To a Document Type?

In Umbraco it is possible to assign multiple templates to a document type. I personally tend to avoid doing this, however, it is possible. If you want to associate multiple templates to controllers, how do you set which controller and template will be called? For each template that is associated to your document type, you can create additional custom actions within your controller. For example, assuming we had a document type called umbHomePage, if you also had a template asscoiated with the controller called umbHomePage like this:

How To Add Your Own Controller and View Model In Umbraco 2

You would create an action method called umbHomePage in your controller. This action method would map to the teplate name. This method would be called in preference over the default index action method whenever the document type is called with that template associated. The code to create this controller is shown below:

In this example, when the page is requested, umbHomePage will be hit first. If the MVC pipeline can't find a matching action method, the default 'Index' action will be called. This is why you can always use an Index action and makes your code cleaner. This override feature is pretty nifty as it gives you a lot of control over how the page is rendered. Now we have a controller set-up, the next step is to focus on the M part of MVC, the view model.

Creating a View Modell

What object should you pass into your view? It is highly likely that you want all the pages data to be passwed down, as well as any custom properties. The code for the view model is shown below:

You can name your custom view model anything you want, however, in general, a good naming convention should mimic the name of the controller you are using postfixed with the term ViewModel. There are a few view model patterns you can use to pass data into a view. The most used pattern, invovles making your view model inherit from RenderModel. In this pattern you define constructor, that accepts the CurrentPage as an argument. Without doing this, the only properties that you will have access to in the template will be the ones you define in the view model yourself.

After you have defined your view model, the next step is create the view model in your controller and pass it to the view:

The code above is pretty self-explanatory. We pass the current page object into in the constructor into the view model. We then pass the view model back to our template using CreateTemplate()

Inheriting For The View Model In The Template

The last bit of the puzzle is to access the view model in the template. Out of the box, a view will use UmbracoTemplatePage as the backing type like this:

Using this new pattern, we also want to tell the template to inherit from UmbracoViewPage instead. UmbracoViewPage uses generics. for T pass in the view model you want to use in your view, like this:

You shoul dnot have a working page 💥

How To Add Your Own Controller and View Model In Umbraco 3

You are now a Umbraco route hi-jacking ninja 🐱‍👤. You know how to hook into the Umbraco pipeline and get a custom controller to intercept any requests for a specific document type.  Happy Coding 🤘