Master Pages, Themes, and Localization

This section documents ASP.NET Web Forms on .NET Framework 4.8.1, the last and permanent version of Web Forms — the page life cycle and postback model, ViewState and control state, server controls, validation controls, master pages and themes, data-bound controls, and the provider-based security model — as described by the official documentation at Microsoft Learn and the ASP.NET previous-versions archive, which are the reference these pages are written and verified against.

Web Forms receives security fixes only and has no forward path onto modern .NET (.NET Framework 4.8.1 is Microsoft’s last version of .NET Framework; Web Forms itself never shipped on .NET Core/.NET 5+). It remains supported for existing applications running on Windows but is not recommended for new development — see Choosing an ASP.NET Framework and Migrating to Modern ASP.NET for what that means in practice.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

This page covers the three mechanisms Web Forms uses to keep a site’s shared layout, look, navigation, and language consistent across many pages, without repeating markup or logic on each one.

Master pages

A master page (.master) defines the shared chrome — header, navigation, footer — around one or more named ContentPlaceHolder regions that content pages fill in:

<%-- Site.master --%>
<%@ Master Language="C#" CodeBehind="Site.master.cs" Inherits="WebFormsApp.SiteMaster" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
</head>
<body>
    <form id="form1" runat="server">
        <header>My Site</header>
        <asp:ContentPlaceHolder ID="MainContent" runat="server" />
        <footer>&copy; 2026</footer>
    </form>
</body>
</html>
<%-- Default.aspx --%>
<%@ Page Language="C#" MasterPageFile="~/Site.master"
    CodeBehind="Default.aspx.cs" Inherits="WebFormsApp.Default" Title="Home" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <h1>Welcome</h1>
</asp:Content>

Nested masters let a section of a site (e.g. an admin area) layer its own shared chrome on top of the site-wide master, by giving the nested master its own MasterPageFile attribute and using ContentPlaceHolder`s inside `Content blocks.

@MasterType and typed Master access

By default, Page.Master is typed as the base MasterPage class — accessing a custom member requires a cast. @MasterType gives a strongly typed, IntelliSense-friendly Master property instead:

<%@ MasterType VirtualPath="~/Site.master" %>
protected void Page_Load(object sender, EventArgs e)
{
    Master.SetPageHeading("Dashboard"); // strongly typed, no cast needed
}

Dynamic master selection

Because the master page is applied during the Initialization stage, it can only be changed in or before PreInit — any later is too late:

protected override void OnPreInit(EventArgs e)
{
    base.OnPreInit(e);
    MasterPageFile = Request.IsAuthenticated ? "~/MemberSite.master" : "~/PublicSite.master";
}

Themes and skins

A theme under App_Themes/<ThemeName>/ bundles CSS files (applied automatically) and .skin files, which set default property values for a control type site-wide:

<%-- App_Themes/Corporate/Buttons.skin --%>
<asp:Button runat="server" CssClass="btn btn-corporate" Font-Size="14px" />
<%@ Page Theme="Corporate" ... %> <%-- StyleSheetTheme="Corporate" is the low-priority variant --%>

Theme overrides any conflicting properties set in markup; StyleSheetTheme applies first and is itself overridable by markup — the choice determines whether a theme is a hard site-wide policy (Theme) or a default a specific page can locally override (StyleSheetTheme). See ASP.NET Themes and Skins.

Site navigation

Web.sitemap declares the site’s logical page hierarchy in XML:

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="~/Default.aspx" title="Home">
    <siteMapNode url="~/Products/Default.aspx" title="Products">
      <siteMapNode url="~/Products/Details.aspx" title="Product Details" />
    </siteMapNode>
    <siteMapNode url="~/About.aspx" title="About" />
  </siteMapNode>
</siteMap>

SiteMapDataSource exposes that hierarchy to navigation controls: SiteMapPath (a breadcrumb trail), Menu, and TreeView:

<asp:SiteMapDataSource ID="SiteMap1" runat="server" />
<asp:Menu ID="MainMenu" runat="server" DataSourceID="SiteMap1" Orientation="Horizontal" />
<asp:SiteMapPath ID="Breadcrumb" runat="server" />

URL routing for Web Forms

System.Web.Routing lets .aspx pages be reached through friendly, parameterized URLs instead of a literal file path, registered in global.asax:

// Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

private static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("ProductDetails", "products/{category}/{id}", "~/Products/Details.aspx");
}
// Products/Details.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    string category = (string)Page.RouteData.Values["category"];
    string id = (string)Page.RouteData.Values["id"];
}

See ASP.NET Routing. This pre-dates and is unrelated to `System.Web.Routing’s reuse by ASP.NET MVC; see Model Binding and Modern Web Forms for the 4.5+ "friendly URLs" feature layered on top.

Localization

Web Forms localizes both static markup and code:

  • Culture/UICulture on @Page, or set programmatically, control number/date formatting and resource lookup respectively:

    protected override void InitializeCulture()
    {
        string lang = Request.UserLanguages?.FirstOrDefault() ?? "en-US";
        UICulture = lang;
        Culture = lang;
        base.InitializeCulture();
    }

    InitializeCulture must be overridden (rather than set in Page_Load) because culture must be established before the page’s resource-driven markup is parsed, earlier than PreInit.

  • Implicit localization — meta:resourcekey on a control pulls matching entries from the page’s App_LocalResources/Default.aspx.resx (and culture-specific .fr.resx, etc.) automatically:

    <asp:Label ID="GreetingLabel" runat="server" meta:resourcekey="GreetingLabelResource1" />
    <%-- App_LocalResources/Default.aspx.resx contains key "GreetingLabelResource1.Text" --%>
  • Explicit expressions — <%$ Resources: %> reads from App_GlobalResources anywhere in markup:

    <asp:Label ID="FooterLabel" runat="server"
        Text="<%$ Resources:Common, CopyrightNotice %>" />