This post was imported from FARMCode.org which has been discontinued. These posts now exist here as an archive. They may contain broken links and images.
I’ve always had this idea in my head that one of the downfalls of using Umbraco when coming form standard ASP.Net web application was the missing code-behind files. You know, when you create a new web application and add an .aspx page to it it conveniently comes with a .cs and design.cs file. Most of the time I would even let the code-behind file inherit from my own custom Page/MasterPage implementation, e.g. a SecuredPage that comes with various properties and methods to handle authentication. Although Umbraco uses regular masterpages (if you haven’t turned it off in the web.config) all you get in the backoffice is the actual page template. Now, don’t get me wrong: I love the way Umbraco let’s you edit all aspects of your site via the backend and gives you the utmost flexibility and 100% control over the output, presented in a refreshingly simple manner. Yet sometimes you need a bit more, and it’s just another clear plus for Umbraco that you are able do the following without ever having to modify the core.

The 'aha' moment that it is actually quite easy to add code-behind files to Umbraco masterpages came to me when I had to port a quite big ASP.Net website to Umbraco. The website had grown organically over the years with lots of custom templates, user controls, etc. The site also had multi-language support, all of which was handled in the code-behind files of the pages. The goal was to get it over to Umbraco as quick as possible, then rework the functionality bit by bit. So I started by creating a new Umbraco site and ‘wrapped’ it in a web application project in Visual Studio.

 

1-28-2011 5-00-55 PM

[Please refer to the comments below to find more information on how to set this up in Visual Studio.]

After adding a couple of document types and templates in Umbraco the masterpages folder looks something like this:

1-28-2011 5-28-34 PM

The Root.master file is the main master page, Page1.master and Page2.master are nested master pages in Umbraco. I’ve included all three of them in the solution. Now it’s time to create the code-behind file: right-click on the masterpages folder and add three C# classes and name them Root.master.cs, Page1.master.cs and Page2.master.cs. The result should be something like this:

1-28-2011 5-29-38 PM

Visual Studio automatically groups them together, fantastic. Yet they are not really hooked up yet, VS does the grouping just based on file names. The master directive on Root.master currently looks like this:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %>

To hook up the cs file we need to add the CodeBehind and Inherits attributes like so:

<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" CodeBehind="Root.master.cs" Inherits="Umbraco_4._6._1.masterpages.Root"%>

You should get an error at this point as the compiler complains that Root is not convertible to System.Web.UI.MasterPage, so we need to fix this in the cs file as well by making the class partial (necessary if you want to later add designer files as well) and inheriting from System.Web.UI.MasterPage. An empty Page_Load message can’t hurt as well:

using System; namespace Umbraco4_6_1.masterpages { public partial class Root : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { } } }

You should now be able to switch between both files by pressing F7 in Visual Studio. Let’s try to add a Property and reference that from the template:

public string Message { get; set; } protected void Page_Load(object sender, EventArgs e) { Message = "All the best from your code-behind file!! :)"; }

and something like this on the template:

<div> <%= Message %> </div>

Now we just need to compile the project and navigate to a content page that uses the Root template to see the message.

 

Adding designer files

[As Simon Dingley pointed out below there is an even easier way to create the designer files: right-click on the master.aspx page and select "Convert to web application", which will create the .designer file for the selected item.]

We can also add a designer file to the duo to make things even better. After adding Root.master.designer.cs, Page1.master.designer.cs and Page2.master.designer.cs the solution looks like this:

1-28-2011 5-49-22 PM

Visual Studio is now rightfully complaining that it got duplicate definitions for the classes and even suggests to add the partial keyword, which we will quickly do. After that is all working and compiling nicely we need to give Visual Studio control over the designer files. That is easily accomplished by slightly modifying each .master file (e.g. by adding a single space to an empty line) and saving it, VS will do the rest for you. The most important thing this will do for you is to reference all controls you add to the template so they are available for use in the code-behind file.

Now let’s try to modify the message value from the code-behind of Page1 by adding

protected void Page_Load(object sender, EventArgs e) { ((Root) Master).Message = "Hello from the nested master page!"; }

to it. Browsing to any Umbraco page that uses the Page1 template will now show the new message.