Click here to Skip to main content
15,879,535 members
Articles / All Topics

SharePoint: Dynamically Change Master Page

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
3 Nov 2009CPOL6 min read 76.9K   11   4
SharePoint branding is possible with either modification of default master or modification of default CSS. When we develop asp.net application we may need to change master page dynamically based on some criterion.

SharePoint branding is possible with either modification of default master or modification of default CSS. When we develop an ASP.NET application, we may need to change master page dynamically based on some criterion. For example, in your site you have three groups of users: anonymous, authenticated normal user and site admin(s). Now based on the user group, you need to change the site layout. So this requirement can easily be met with changing master page dynamically based on user’s login status.

How to Change Master Page in ASP.NET?

SharePoint is an ASP.NET application developer by Microsoft. So let’s see how we can change master page in an ASP.NET application. If you develop an ASP.NET application, then you can easily change the master page dynamically by changing the master page in PreInit event. You can check user’s login status in every page’s PreInit event. But if you have hundreds of pages, then you don't want to write the same code again and again in every page. So in the case the one approach might be to create a class which will inherit from Page class. Say the class is MyBasePage. In MyBasePage’s Page_PreInit event, you can change the master page based on condition. The class is shown below:

C#
public class MyBasePage : System.Web.UI.Page
{
    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (CurrentUser.UserType == UserType.Admin)
        {
            MasterPageFile = "~/MasterPages/AdminMaster.master";
        }
        else if (CurrentUser.UserType == UserType.NormalAuthenitcated)
        {
            MasterPageFile = "~/MasterPages/NormalAuthenticatedMaster.master";
        }
        else
        {
            MasterPageFile = "~/MasterPages/AnonymouskMaster.master";
        }
    }
}

Now every web page can inherit from MyBasePage. To do so, you need to modify web page’s code behind file to change the inheritance from System.Web.UI.Page to MyBasePage as shown below:

C#
public partial class HomePage : MyBasePage 
{
      protected void Page_Load(object sender, EventArgs e)
      {

      }
}

How to Change Master Page in SharePoint?

Knowing the concept of “Change master page in PreInit event”, you may think I’m done. Wait! Don’t stop reading. I have not started yet for SharePoint. SharePoint has its own pages which have installed as part of the SharePoint installation. Those pages’ code behind is complied in DLL. How you are going to modify code in those pages’ code behind file? So you can’t override PreInit event as it was possible in ASP.NET application as you don’t have source code for SharePoint pages. Don’t give up. There’s a workaround where there’s a problem. We'll use HttpModule to hook our code in SharePoint Pages’ PreInit event. But first of all, let me explain in brief how ASP.NET pipeline processing works.

ASP.NET Pipeline Processing

ASP.NET request processing is based on pipeline model as shown in figure 1. Each request goes through a number of modules where each module can modify the request. Finally the request is passed to a Handler which processes the final request.

image

Figure 1: ASP.NET Request/response pipeline.

Usually each request is handled by multiple modules and one handler. In the above request/response pipeline, we don’t want to process the final request but want to modify the request to add a PreInit event handler for ASP.NET page.

Develop an HttpModule to Attach PreInit Event Handler

To develop a custom HttpModule we need to write a class which will inherit from System.Web.IHttpModule. IHttpModule defines two methods to implement: Init and Dispose. Init method will be invoked when the module will be initialized and dispose method will be invoked when the module will be disposed.

C#
public class DynamicMasterPageModule : IHttpModule
{
    public void Dispose()
    {
    }
    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += 
		new EventHandler(context_PreRequestHandlerExecute);
    }
    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        Page page = HttpContext.Current.CurrentHandler as Page;
        if (page != null)
        {
            page.PreInit += new EventHandler(page_PreInit);
        }
    }
    void page_PreInit(object sender, EventArgs e)
    {
    }
} 

As shown in the above code block, in Init method I have hooked an event handler for PreRequestHandlerExecute event. The PreRequestHandlerExecute fires just before ASP.NET starts executing a page. In the context_PreRequestHandlerExecute method, we can get the current executing page by accessing the CurrentHandler object. If current handler is for a page, then the page variable will not be null. In case of other request (say web service request) the CurrentHandler casting to page object will return null. Now we can modify the master page in the page_PreInit method. So you are thinking it’s done. Wait! There’s more to make it working in SharePoint. Let’s take a tour on how SharePoint guides us to change master page.

SharePoint Master Page

SharePoint has a default master page. But if you want, you can develop your own master page for SharePoint in SharePoint designer. To refer a master page from content page in SharePoint, there are four tokens available. In normal ASP.NET application, we set the master page from content page by setting the Page.MasterPageFile property of the page to the location of the master page as shown below:

C#
Page.MasterPageFile="path to master file"; 

But in SharePoint, this MasterPageFile property is used differently. It may be or may be not the location of the master page file in SharePoint. In SharePoint MasterPageFile can take four predefined values (called tokens). Based on the token values, SharePoint determines which master page to use for the page (default, custom, site collection, etc). The four tokens fall into two categories: dynamic and static. Static token is used by itself to define the master page location. The two static tokens are described below:

  • Token "~site/MasterPageName.master"

In this token, the ~site refers to site relative URL and MasterPageName.master is the name of the master page. So if you provide the token “~site/masterpages/MyMaster.master” and your site URL is like http://sitecollection/site1 then the master page URL will be http://sitecollection/site1/masterpages/MyMaster.master.

  • Token "~sitecollection/MasterPageName.master"

Here the token ~sitecollection points to the site collection URL. So if your site collection URL is http://sitecolleciton then the master page location will be http://sitecolection/MasterPageName.master.

Dynamic token doesn’t provide the master page location rather it points where to get the master page file location. Dynamic tokens are exact values and you can’t change them like static token. The two dynamic token are described below:

  1. Token "~masterurl/default.master"

When you’ll set the value like Page.MasterPageFile= "~masterurl/default.master", SharePoint will use the master page provided in SPWeb.MasterUrl property. So if you set master page file to this token, you need to ensure that you have provided the master page location to SPWeb.MasterUrl property. FYI, the dynamic token is not changeable and you need to provide exact “~masterurl/default.master”.

  • Token "~masterurl/custom.master"

When you will use this token, then SharePoint will use SPWeb.CustomMasterPageUrl property. So along with setting this token, you also need to set the SPWeb.CustomMasterPageUrl property. FYI, the dynamic token is not changeable and you need to provide exact “~masterurl/default.master”.

Develop Custom Master Page in SharePoint

  1. Create a custom master page

    For Developing SharePoint master page, we can use SharePoint designer. The easiest way to create a master page is to copy an existing master page in SharePoint Designer and paste it and then modify it.

  2. Make the master page you developed as Custom master page

    But once you have developed a master page in SharePoint, it doesn’t become a custom master page automatically. You can set your master page as custom one from SharePoint Designer. Open your site in SharePoint Designer and then navigate to _catalogs > Masterpage and then select your master page. Finally right click on the master page to bring the context menu and click “Set as Custom Master page” from the context menu. To following figure shows how to set a master page as custom one from SharePoint designer.

    image

    Figure 2: How to set custom master page in SharePoint Designer.
  3. User your custom Master Page in PreInit event.

    In the following code block, I have read the page number from web.cofing and if I find page number 1 then I use the custom1.master, for page number 2 I use custom2.master. Either I use default master page. In real life scenario, you will change the master page based on some other criterion.

    C#
    void page_PreInit(object sender, EventArgs e)
         {
             Page page = sender as Page;
    
             string pageNo = ConfigurationManager.AppSettings["MasterPageNo"];
    
             if (page != null)
             {
                 if (pageNo.Equals("1"))
                 {
                     page.MasterPageFile = "~masterurl/custom.master";
                     if (SPContext.Current != null)
                     {
                         SPContext.Current.Web.CustomMasterUrl = 
    				"/_catalogs/masterpage/custom1.master";
                     }
                 }
                 else if (pageNo.Equals("2"))
                 {
                     page.MasterPageFile = "~masterurl/custom.master";
                     if (SPContext.Current != null)
                     {
                         SPContext.Current.Web.CustomMasterUrl = 
    				"/_catalogs/masterpage/custom2.master";
                     }
                 }
                 else
                 {
                     page.MasterPageFile = "~masterurl/default.master";
                     if (SPContext.Current != null)
                     {
                         SPContext.Current.Web.MasterUrl = 
    				"/_catalogs/masterpage/default.master";
                     }
                 }
             }

    In the code block above, you can just comment out the else section. I have just used this to show that you can also set the default master page. You can skip this code block as you don’t need to set the default master page as it’s already set by default.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect ImpleVista Aps
Denmark Denmark
Sohel has more than six years of experience in professional software development with extensive involvement in Web based Object-Oriented, Multi-Tiered application design and development. He's Familiar with Test Driven Development (TDD) and refactoring techniques as well as having expertise in architecturing large enterprise applications. He has Experience in working with Content Management System and Portal Management System tools like SharePoint, DotNetNuke, Ektron.

Over last few years, he’s involved in development with projects on Microsoft SharePoint and received Microsoft MVP for SharePoint Server Development in the year 2011 and 2012. Currently he's working in a software company located Copenhagen,Denmark on a project integrating SharePoint and SAP. You can read his popular blog at: http://ranaictiu-technicalblog.blogspot.com

Comments and Discussions

 
QuestionQuestion Pin
Member 844096918-Nov-13 10:02
Member 844096918-Nov-13 10:02 
SuggestionCustom master page with subclass in code-behind Pin
Member 14778511-Jun-12 17:13
Member 14778511-Jun-12 17:13 
GeneralMy vote of 5 Pin
PerlDev23-Feb-11 3:43
PerlDev23-Feb-11 3:43 
GeneralMy vote of 5 Pin
Eugene Rosenfeld24-Sep-10 7:29
Eugene Rosenfeld24-Sep-10 7:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.