Migration to SharePoint 2013: Unable to change the Master Page of a Publishing Portal

A few days ago I was supporting a customer during the migration of the Corporate Intranet (SharePoint 2010) to SharePoint 2013.

One of the “manual configurations” that we needed to apply after the attach&mount step was to change the master page of a bunch of Team Sites, all having the Publishing Features activated.

Strangely enough, this operation succeeded on most of these sites but one, where we got the dreaded “Unexpected error”.

This error went away after performing a Version Upgrade of the site collection.

Mmhh…. I started investigating 🙂

I was just curious, so I opened up the page markup with the intention to ensure that the behavior of this Application Page was the one I expected.

Now, the “magic” of Compatibility Levels relies on having two versions of the SharePoint Root Hive (14 and 15), and on the SharePoint modules to pick up the correct version of pages and resources based on the Compatibility Level of the site collection.

Therefore, I started comparing the two versions of ChangeSiteMasterPage.aspx.

If you browse the14 version of this page, you should see something similar to the picture below:

image

Whereas this is the corresponding “15” version:

image

As you may notice, these pages are a little bit different:

  1. The 15 version supports Device Channels, which the 14 versions obviously does not (hence the difference in the Site Master Page and the System Master Page sections)
  2. The 15 version supports the propagation of Theme settings to the child webs,  which the 14 versions obviously does not (hence the new Theme section)

See, for example, the following code snippet (representing the Theme section) that is defined only in the 15 version of the page:

<!-- Theme inheritance section -->
            <wssuc:InputFormSection Title="<%$Resources:cms,areachromesettings_themeinheritance_header%>"
                Description="<%$Resources:cms,areachromesettings_themeinheritance_description%>"
                Collapsible="true"
                Collapsed="true"
                runat="server">
                <Template_InputFormControls>
                    <wssuc:InputFormControl runat="server">
                        <Template_Control>
                            <table>
                                <wssawc:InputFormCheckBox ID="inheritThemeCheckbox" LabelText="<%$Resources:cms, areachromesettings_themeinheritance_inherittheme_checkboxtext%>" runat="server"/>
                            </table>
                            <table>
                                <wssawc:InputFormCheckBox ID="resetThemeSubSitesCheckBox" LabelText="<%$Resources:cms, areachromesettings_themeinheritance_resetsubsite_checkboxtext%>" runat="server"/>
                            </table>
                        </Template_Control>
                    </wssuc:InputFormControl>
                </Template_InputFormControls>
            </wssuc:InputFormSection>

 

Now… this is perfectly fine, as long as any logic in the code behind takes the Compatibility Level into account when performing operation on the UI (i.e. referencing controls). This is typically done by checking the CompatibilityLevel property of the SPSite object:

private void InitThemeInheritanceControls(bool isInheriting, bool isRoot, CheckBox inheritCheckbox, CheckBox resetSubSitesCheckbox)
{
    if (base.Site.CompatibilityLevel >= 15)
    {
        if (isRoot)
        {
            isInheriting = false;
            inheritCheckbox.Enabled = false;
        }
        inheritCheckbox.Checked = isInheriting;
        resetSubSitesCheckbox.Checked = false;
    }
}

 

But when no check is performed against the compatibility level, the code behind should rely only on features/controls that are defined in both version of the page, right?

Now, take a look at the OnLoad event handler of the AreaChromeSettingsPage, which is the code behind class for ChangeSiteMasterPage.aspx (see Microsoft.SharePoint.Publishing.Internal.CodeBehind.AreaChromeSettingsPage in
Microsoft.SharePoint.Publishing, Version=15.0.0.0):

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    this.EnsureChildControls();
    if (!this.Page.IsPostBack)
    {
        this.LoadValues();
        if (base.Web.Webs.Count == 0)
        {
            this.resetSystemMasterPageSubSitesCheckBox.Visible = false;
            this.resetSubSitesCheckBox.Visible = false;
            this.resetAlternateCssSubSitesCheckBox.Visible = false;
            this.resetThemeSubSitesCheckBox.Visible = false;
        }
    }
    base.ConfigureCancelButton(this.BtnCancel);
}

 

See what I mean?

This snippet is supposed to disable a bunch of controls (the Check Boxes that allow you to apply the new settings to all child webs) if the context web has no child web at all.

Unfortunately, there’s no CompatibilityLevel check, so the following line:

this.resetThemeSubSitesCheckBox.Visible = false;

will fail if:

  1. The Site is in 14 mode
  2. The Site has child webs

That was exactly my case.

You can easily reproduce this behavior:

  1. Create a new, out-of-the-box Publishing Portal on a SP2010 box
  2. Migrate it to a SP2013 farm
  3. Do not perform any Version Upgrade and try to navigate to the “Change Master Page” page. It should work fine, since the default SP2010 Publishing Portal has a couple of subwebs (Search and Press Releases)
  4. Delete both subwebs and try to load the page again. The page should be broken now

Funny, isnt’t it? 🙁

One thought on “Migration to SharePoint 2013: Unable to change the Master Page of a Publishing Portal”

Leave a Reply

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