Upgrading to master pages should be straightforward, but there are a few considerations:
- Every effort has been made to ensure that custom code will work after the upgrade. However, there are some breaking changes, which may require you to change existing custom code.
- Likewise, bespoke code could potentially have some issues if you are manipulating controls outside of the bespoke control itself.
To aid the transition to master pages, we’ve developed master pages as a publishing server option. This allows you to migrate to master pages at your own pace, either by creating a new publishing server, or updating an existing server such as your preview site. Both of these options let you test your site using master pages and allowing you to check that any bespoke or custom code you are using is compatible.
The first step to migrating your site to master pages is to ensure that the custom code you are using is supported. When validating master pages across a range of customer sites during testing we identified a number of common custom code snippets that no longer worked.
Before upgrading your site to use master pages, we recommend that you review the following breaking changes.
Client ID’s of controls
In master pages the ID attribute of a control’s HTML element will have changed as controls are now placed inside master pages or user controls. This may affect any JS / CSS that references the ID.
Contensis controls will work in either Auto ID or Static ID mode.
Reference controls outside of the current template
In the Legacy ASPX publishing model, all the templates and sub templates in a page would get merged into a flat file; because of this, everything would be in the same scope enabling custom code to interact with controls outside of it’s sub template.
With master pages, the scenario has changed. In master pages, the pages are put together in a hierarchy. This means that a subcontrol, or a bespoke control, cannot assume it can directly interact with any other control on the page, as it may be out of scope.
To fix this issue you must get controls using the GetControl function. This will search through the hierarchy for you and return the control you’re looking for. It’s a good idea to do a null reference check, just in case that control ever gets removed from the page, as illustrated in the example below.
Pre 8.3 Master Pages
controlInPageTemplate.Text = "Some Text from sub template"
8.3 Master Pages
dim controlInTemplate as Literal = TryCast(ParentPage.GetControl("controlInTemplate"), Literal)if controlInTemplate IsNot Nothing thencontrolInTemplate.Text = "Some Text from sub template"end if
Use of MyGetControl in custom code
The behaviour of the MyGetControl with master page sub templates has changed. In sub templates the second argument of component is always ignored. This is because within sub templates the component is not needed to determine the required control.
Using MyGetControl or FindControl will only look for controls within the template rather than across the whole page.
Get the page form
While previously you may have used FindControl to get the form element, you can now simply use Page.Form.
Pre 8.3 Master Pages
Dim formwrapper As HtmlForm = CType(Page.FindControl("form1"), HtmlForm)
8.3 Master Pages
Dim formwrapper As HtmlForm = Page.Form
Determine if a placeholder has content
Because of the new hierarchical structure, the classic methods for determining if a placeholder has content will no longer work, for example, you can’t be sure that Controls. Count will be 0, as it may have other child controls within it.
To tackle this, we’ve introduced a ContensisControls property which simulates the Controls property in Legacy ASPX, so it will take out all the Master Page controls that are in the background to make the pages work out of it’s collection, so you can check if ContensisControls.Count is 0. This allows a straight swap into a lot of custom code, as you simply replace Controls with ContensisControls, see our example below.
We’ve also introduced a new function IsEmptyOrDefaultContent. This function will carry out all the necessary logic, it trims, checks it’s not empty or simply whitespace, verify that no user controls have been added, before returning a boolean. See the example below and the “New Controls” section for more information.
Finding existing custom code that needs to be changed is easy as you can search on Custom Code in the ZenQL Search, searching for Control.Controls.Count
Pre 8.3 Master Pages
if Control.Controls.Count = 0 AndAlso (Value = "" OrElse Value = "[Some Default Text]") then' Control Is Emptyend if
8.3 Master Pages - ContensisControls method
if Control.ContensisControls.Count = 0 AndAlso (Value = "" OrElse Value = "[Some Default Text]") then' Control Is Emptyend if
8.3 Master Pages - IsEmptyOrDefaultContent method
if Control.IsEmptyOrDefaultContent("[Some Default Text]") then' Control Is Emptyend if
Here is a list of the new methods we have added, which you’ll be able to use in custom code.
Public Overridable Function IsEmptyOrDefaultContent(defaultContent As String) As Boolean
Public Overridable Function IsEmptyOrDefaultContent(defaultContent As String, stripHtml As Boolean) As Boolean
These functions allow you to check if a placeholder is empty or has default content. The second argument allows you to strip HTML as part of the check, so empty HTML tags will still be treated as empty content. You can see an example of this code in the Determining if a placeholder has content section.
Public Overridable ReadOnly Property ContensisControls As ControlCollection
This function will return a control collection of all the Controls in the placeholder, taking into account the hierarchical structure.
Public Overridable Function HasContensisControls() As Boolean
This function will return a boolean that determines whether a placeholder contains controls.
Public Overridable Function HasContensisText() As Boolean
This function will return a boolean that determines whether a placeholder contains only text.
The page events no longer exist when used in custom code as we are now using user controls. So you’re limited to the following events:
||Occurs when a user ends a transaction.(Inherited from TemplateControl.)
||Occurs when a transaction completes.(Inherited from TemplateControl.)
||Occurs when the server control binds to a data source.(Inherited from Control.)
||Occurs when a server control is released from memory, which is the last stage of the server control lifecycle when an ASP.NET page is requested.(Inherited from Control.)
||Occurs when an unhandled exception is thrown.(Inherited from TemplateControl.)
||Occurs when the server control is initialized, which is the first step in its lifecycle.(Inherited from Control.)
||Occurs when the server control is loaded into the Page object.(Inherited from Control.)
||Occurs after the Control object is loaded but prior to rendering.(Inherited from Control.)
||Occurs when the server control is unloaded from memory.(Inherited from Control.)
Note: While we’ve worked to cover the widest range of examples, your installation may have custom code not covered by these common examples. We recommend you review your templates for custom code to ensure your site is behaving as expected once you’ve migrated to master pages.
Search for custom code
To make the process of locating custom code easy, we’ve updated the Contensis search to support a new property for filtering by custom code. This will enable you to find templates with custom code that matches the strings outlined above.