Chapter 3: WebPages Layout
What is Page Layout in ASP.NET Web Pages?
It’s a system to create a consistent look and structure across all (or many) pages using:
- One layout template file (usually named _Layout.cshtml)
- Content pages that “plug into” this template
- Special Razor helpers like @RenderBody(), @RenderSection(), and @RenderPage()
Key players:
- _Layout.cshtml → the master template (HTML skeleton + common parts)
- Content pages (like Index.cshtml, About.cshtml) → only the unique stuff
- @RenderBody() → the “hole” where your page’s main content goes
- @RenderSection() → optional extra holes for things like page-specific scripts or styles
- @RenderPage() → way to include reusable mini-blocks (like a header or sidebar)
Important convention — Files starting with _ (underscore) are protected. You can’t browse them directly in the browser (e.g., /_Layout.cshtml gives 404). Perfect for templates!
Why Use It? (Teacher motivation speech)
- Consistency → same header/footer everywhere
- Easy updates → change one file, all pages update
- Cleaner code → content pages are short & focused
- Professional → looks like modern sites (think WordPress themes)
This is almost identical to how ASP.NET Core Razor Pages layouts work today — so learning it now pays off later!
How It Works – Step by Step with Real Examples
Step 1: Create the Layout File – _Layout.cshtml
Put this in the root or in a Shared folder (common practice).
_Layout.cshtml (basic version)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>My Awesome Website - @RenderSection("title", required: false)</title> <link href="~/css/site.css" rel="stylesheet" /> <!-- common CSS --> </head> <body> <header> <h1>Welcome to Webliance Site 🌟</h1> <nav> <a href="/">Home</a> | <a href="/About">About</a> | <a href="/Contact">Contact</a> </nav> </header> <main> @RenderBody() <!-- ← MAGIC: where your page content gets inserted --> </main> <footer> <p>&copy; @DateTime.Now.Year Webliance - Hyderabad, India</p> </footer> <!-- Common scripts at bottom --> <script src="~/js/site.js"></script> <!-- Optional page-specific scripts/styles go here --> @RenderSection("scripts", required: false) </body> </html> |
Key parts explained:
- @RenderBody() → mandatory! This is where the content from your page (Index.cshtml etc.) will appear.
- @RenderSection(“scripts”, required: false) → optional named section. Content pages can fill it if they want (e.g., add extra JS).
- required: false = no error if page doesn’t provide it
- If required: true → every page must define that section or error!
- You can have many @RenderSection() calls (e.g., “head”, “styles”, “footer-scripts”)
Step 2: Create a Content Page that Uses the Layout
Index.cshtml (your home page)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
@{ Layout = "~/_Layout.cshtml"; // ← Link to the layout ( ~ means root) // Optional: set page title for the section } @section title { Home Page } <h2>Hello from Hyderabad! 🇮🇳</h2> <p>This is the main content of the home page.</p> <p>Server time: @DateTime.Now</p> <!-- If this page needs extra JavaScript --> @section scripts { <script> alert("Welcome home!"); </script> } |
What happens when browser requests /Index ?
- Server loads Index.cshtml
- Sees Layout = … → loads _Layout.cshtml instead
- Runs Index’s code blocks and sections
- Renders _Layout’s HTML
- Inserts Index’s main content at @RenderBody()
- Inserts the @section scripts { … } at @RenderSection(“scripts”, …)
- Sends beautiful full HTML to browser
Step 3: Reusable Blocks with @RenderPage()
Sometimes you want small reusable pieces (not full layout).
Create _Header.cshtml
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@{ var pageTitle = "Default Title"; // default // If passed from RenderPage if (PageData["Title"] != null) { pageTitle = PageData["Title"]; } } <div class="header"> <h2>@pageTitle</h2> <p>Hyderabad's Favorite Learning Site</p> </div> |
Then in _Layout.cshtml or any page:
|
0 1 2 3 4 5 6 |
@RenderPage("_Header.cshtml", new { Title = "Custom Home Title" }) |
Or simpler (no params):
|
0 1 2 3 4 5 6 |
@RenderPage("_Footer.cshtml") |
@RenderPage() inserts the entire output of that file right there.
Full Picture – Folder Structure (Recommended)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
App_Data/ (for databases) css/ site.css js/ site.js Shared/ (common place for layouts & includes) _Layout.cshtml _Header.cshtml _Footer.cshtml Index.cshtml (uses Layout = "~/Shared/_Layout.cshtml") About.cshtml Contact.cshtml |
Bonus Teacher Tips (2026 style)
- Use PageData[“key”] or ViewBag.key to pass data to included files (like title).
- For global startup stuff (DB connection strings, email settings) → use _AppStart.cshtml (runs automatically on app start, also protected by _).
- In modern ASP.NET Core → same ideas, but folder is usually Pages/Shared/_Layout.cshtml, and it’s @await RenderSectionAsync(“scripts”, false) (async version).
Summary – Like Closing the Blackboard
ASP.NET Web Pages Page Layout = template system with:
- _Layout.cshtml as master template
- @RenderBody() for main content
- @RenderSection() for optional extras (scripts, head stuff)
- @RenderPage() for small reusable includes
- Layout = “…” in content pages to connect them
One change in layout → entire site updates. Magic!
Questions for homework? 😄
- Want to see a full site example with menu highlighting active page?
- How to make different layouts for admin vs public pages?
- Difference from Classic ASP includes?
- Or next topic: WebPages Folders / Global?
Tell me — next class is ready! Keep building, Webliance — you’re nailing this! 🚀🇮🇳
