How To Add Your Own Controller and View Model In Umbraco

In my last tutorial, we covered how to get data from Umbraco and display it in Umbraco.  If you are new to Umbraco and you haven’t yet read the Umbraco Helper?  then I would head there first.

In today’s guide, I am going to explain how to create your own MVC controllers and intercept the Umbraco routing. After we intercept the Umbraco pipeline, we will then return a custom View Model back to the templates.

Why Use A Controller?

When you work with Umbraco, because of it’s flexibility, you can create a lot of the document types and templates directly in Umbraco.  When your site gets a bit more complex and you need to do things like talk to a business layer to get additional data for a page, unit tests your code, remove logic out of your templates or a host of other things.

Document Types

In How To Create A Document Type In Umbraco and create a page with it I explained about document types.  On most projects, you will usually create one controller for each document type.  To get started, first open Umbraco and find the document types ‘Alias’.

NOTE: If you use the name the controller will not get hit

Umbraco_controller_getting_document_types_name

Next, create a new controller.  When you create a new MVC project the installation wizard should have created a ‘Controllers’ folder.  Depending on how you want to structure your code, you can create your new controller in here, or somewhere else.  I personally like to keep all my C# code in a separate project but for simplicity, I’m assuming you will create you use the default one.  If you are adding MVC to an existing project then you will have to create it yourself.

In case you’re wondering what a controller is…  a normal MVC controller is just a C# code file, that inherits from ‘Controller’ and has controller prefixed in it’ name, so for example MyPageController.  The only real difference with an MVC controller is that it inherits from an Umbraco base controller, rather than a Microsoft one.

If you are new to MVC then this rule of having the controller in the name, is a  Microsoft thing rather than an Umbraco one, so in this example, my alias controller will be called umbHomePage, so my class would be called ‘umbHomePageController’.

After you have created the controller, the next step is to change the type the controller inherits from.  In a standard MVC controller, we inherit from ‘PageController’, in Umbraco we inherit from ‘RenderMvcController’.

public class HomeController : Umbraco.Web.Mvc.RenderMvcController
{
public ActionResult Index(RenderModel model)
{
return base.Index(model);
}
}

If you run your code and try to load your page the ‘Index’ action should be run.

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

You may not have thought about this yet, but what happens if you have several different templates associated to your document type?  You may want different data returned depending on which template the content editor selected, or, you may even want a completely different view displayed all together.

Luckily, Umbraco has thought about this.  For each ‘template’ that is associated to your ‘document type’ you can create a custom action that will be called.  So, for example, if you had a template called ‘HomePage’, with an alias ‘umbHomePage’ set as the template for your ‘document type’

umbraco_controller_template_alias

You could create an action method called ‘umbHomePage’.  This action method would then be called in preference over the index action method whenever the document type is called with that template associated.  The code will look like this:

public class umbHomePageController: Umbraco.Web.Mvc.RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
return CurrentTemplate(model);
}
public ActionResult umbHomePage(RenderModel model)
{
return CurrentTemplate(model);
}
}

When you load your page, umbHomePage will be hit first.  If the MVC pipeline can’t find a matching action method which matches the templates name, then the default ‘Index’ action will be called. This feature is pretty nifty as it gives the developer a lot of control over the mark-up.

Creating a View Model

Now we have a controller set-up, the next stage is to return a custom view model.  When you normally create a view model you will still want all the pages data to be included in it, as well as any custom properties or methods.  The code for the view model is shown below:

{
public class HomeModel : RenderModel
{
public HomeModel(IPublishedContent content)
: base(content)
{
}
public DateTime CurrentDate
{ 
get
{
return DateTime.Now;
}
}
}

First, you can name your custom view model anything you want, but, in general, the view model should mimic the name of the controller you are using.  The entity should inherit from RenderModel.

The next step is to create a constructor, that accepts the CurrentPage, so we can use this data in the template.  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.  Next, in this example I’m returning the current time. After you have defined your view model, the next step is changing your controller to return the view model.

public class umbHomePageController: Umbraco.Web.Mvc.RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
var homeModel = new HomeModel(CurrentPage);
return CurrentTemplate(homeModel);
}
}

The code above is pretty self-explanatory.  We pass the model we get in the constructor into the view model and then pass it back to our template using CreateTemplate().

Inheriting For The View Model In The Template

The last bit of the puzzle is to make the view model available in the template.  In the previous example, the view inherited from UmbracoTemplatePage.

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage

Instead, we want to tell the template to inherit from the model.  We do this by inheriting from UmbracoViewPage and we pass in our new model as the type.

@inherits UmbracoViewPage<SampleSite.Models.HomeModel>

umbraco_controller_displaying_model

Conclusion

In today’s guide, we’ve gone over how to hook into the Umbraco pipeline and get a customer controller to intercept any requests for a specific document type.  We’ve created a custom view model and added some custom business logic and then returned it back to our view. If you are familiar with MVC or other CMS platforms this process should look pretty familiar.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

1 reply

Trackbacks & Pingbacks

  1. […] That’s all you the configuration need. I’m going to assume you have a controller set-up for your document type. If you are unsure how to o this then again, read How To Add Your Own Controller and View Model In Umbraco. […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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