MasterPage to Blazor Layout Migration
Note: This page demonstrates how Web Forms MasterPages are replaced by Blazor Layouts.
Concept Overview
In ASP.NET Web Forms, MasterPages provided a template for consistent page structure.
In Blazor, this is achieved through Layout Components.
Web Forms Approach
Site.Master
<%@ Master Language="C#" %>
<html>
<body>
<div class="header">Header</div>
<asp:ContentPlaceHolder ID="MainContent"
runat="server">
</asp:ContentPlaceHolder>
<div class="footer">Footer</div>
</body>
</html>
MyPage.aspx
<%@ Page MasterPageFile="~/Site.Master" %>
<asp:Content
ContentPlaceHolderID="MainContent"
runat="server">
<h1>Page Content</h1>
</asp:Content>Blazor Approach
MainLayout.razor
@inherits LayoutComponentBase
<div class="header">Header</div>
@Body
<div class="footer">Footer</div>
MyPage.razor
@page "/mypage"
@layout MainLayout
<h1>Page Content</h1>Multiple Content Areas
Web Forms - Multiple ContentPlaceHolders
<asp:ContentPlaceHolder
ID="Header" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder
ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder
ID="Sidebar" runat="server">
</asp:ContentPlaceHolder>Blazor - RenderSection
@RenderSection("Header", required: false)
@Body
@RenderSection("Sidebar", required: false)
In Page:
@section Header {
<h1>Custom Header</h1>
}
<p>Main content</p>
@section Sidebar {
<nav>Sidebar</nav>
}Using MasterPage Components (Migration Helper)
For gradual migration, BlazorWebFormsComponents provides MasterPage and
ContentPlaceHolder components that emulate Web Forms syntax:
Bridge Components (Temporary Migration Aid)
<MasterPage>
<div class="header">
<h1>My Site</h1>
</div>
<ContentPlaceHolder ID="MainContent">
<p>Default content</p>
</ContentPlaceHolder>
<div class="footer">
<p>Footer</p>
</div>
</MasterPage>
With Head Parameter (NEW!)
The MasterPage component now includes a Head parameter that automatically wraps content in <HeadContent>. You can include <title> elements directly:
<MasterPage>
<Head>
<title>My Page - Site Name</title>
<link href="css/site.css" rel="stylesheet" />
<meta name="description" content="My site" />
</Head>
<ChildContent>
<div class="header">
<h1>My Site</h1>
</div>
<ContentPlaceHolder ID="MainContent">
<p>Default content</p>
</ContentPlaceHolder>
</ChildContent>
</MasterPage>
New Feature: The
Head parameter provides a convenient bridge
between Web Forms' <head runat="server"> and Blazor's <HeadContent>.
You can include <title> elements directly in the Head content,
just like in Web Forms, and they will be rendered correctly in the document's <head> section.
Recommendation: Use native Blazor layouts for new development.
The MasterPage components are provided for easier migration but should be
replaced with standard Blazor layouts as part of your modernization effort.
Critical Difference: HTML Head Management
Important: Web Forms MasterPages control the entire HTML document including the
<head> section.
Blazor layouts do NOT control the head - this is a fundamental architectural difference.
Web Forms - Head in MasterPage
<%@ Master Language="C#" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title><%: Page.Title %></title>
<link href="~/css/site.css" rel="stylesheet" />
<asp:ContentPlaceHolder ID="HeadContent"
runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<asp:ContentPlaceHolder ID="MainContent"
runat="server">
</asp:ContentPlaceHolder>
</body>
</html>
Child Page
<%@ Page Title="My Page"
MasterPageFile="~/Site.Master" %>
<asp:Content
ContentPlaceHolderID="HeadContent"
runat="server">
<link href="/css/custom.css" rel="stylesheet" />
</asp:Content>Blazor - Head in App.razor
App.razor (Root)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="css/site.css" rel="stylesheet" />
<HeadOutlet />
</head>
<body>
<Routes />
</body>
</html>
Page
@page "/mypage"
<PageTitle>My Page</PageTitle>
<HeadContent>
<link href="css/custom.css" rel="stylesheet" />
</HeadContent>
<h1>Content</h1>Key Points for Migration
- Static head content (common CSS, meta tags) moves from MasterPage to
App.razor - Page titles use
<PageTitle>component instead ofPage.Titleproperty - Page-specific head content uses
<HeadContent>component instead of ContentPlaceHolder in head - Layouts do NOT define HTML structure - they only wrap body content with
@Body - HeadOutlet is required in App.razor for PageTitle and HeadContent to work
Key Benefits of Blazor Layouts
- Simpler Syntax: No need for ContentPlaceHolder/Content matching
- Type Safety: Layouts are strongly-typed Blazor components
- Better IntelliSense: Full IDE support in Razor files
- Cascading Values: Easy data sharing between layouts and pages
- Component Reusability: Extract shared UI into components
This Page's Layout
This page uses the MainLayout component specified by the
@layout MainLayout directive at the top of this file.
Current Layout: MainLayout
Layout Location: /Components/Layout/MainLayout.razor
Contains: Navigation sidebar, top bar with links, and content area