ASP.NET Core MVC Mastery

Layouts & Sections

3 Views Updated 5/4/2026

Layouts & Sections in ASP.NET Core MVC — Architecting the UI Foundation

Every page on your application shares a common DNA — the header, navigation, footer, and meta tags. Without layouts, you'd be copy-pasting this code across hundreds of views. Layouts in ASP.NET Core MVC let you define this structure once and inject unique content into it from any view, creating a clean, maintainable UI architecture.

1. WHAT Are Layouts?

A Layout is a Razor template (.cshtml) that defines the common HTML skeleton shared by multiple views — the <html>, <head>, <body> tags, navigation bars, footers, and shared CSS/JS references. Individual views then inject their unique content into this skeleton via @RenderBody().

The Architecture
┌──────────────────────────────────────┐
│         _Layout.cshtml               │
│  ┌────────────────────────────────┐  │
│  │  <nav> Navigation Bar </nav>   │  │
│  ├────────────────────────────────┤  │
│  │                                │  │
│  │     @RenderBody()              │  │
│  │     (Your View Content Here)   │  │
│  │                                │  │
│  ├────────────────────────────────┤  │
│  │  <footer> Footer </footer>     │  │
│  ├────────────────────────────────┤  │
│  │  @RenderSection("Scripts")     │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘

2. The Three Pillars: RenderBody, RenderSection, _ViewStart

@RenderBody()

The mandatory placeholder where child view content is injected. Only ONE per layout. Think of it as the "main content area."

@RenderSection()

Named slots that child views can optionally fill. Perfect for page-specific CSS, JavaScript, or sidebar content. Use required: false for optional sections.

_ViewStart.cshtml

Executes before every view in its directory (and subdirectories). Used to set the default layout globally so you don't repeat Layout = "_Layout" in every view.

3. REAL-TIME PRODUCTION EXAMPLES

Example 1: Production-Ready Layout with Multiple Sections

<!-- Views/Shared/_Layout.cshtml -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="@ViewData["MetaDescription"]" />
    <title>@ViewData["Title"] — MyApp</title>

    <!-- Global CSS -->
    <link rel="stylesheet" href="~/css/app.min.css" />

    <!-- Page-specific CSS (optional) -->
    @RenderSection("Styles", required: false)
</head>
<body>
    <!-- Shared Navigation -->
    <partial name="_Navbar" />

    <!-- Flash Messages -->
    <partial name="_Notifications" />

    <!-- MAIN CONTENT — Each view's content renders here -->
    <main class="container py-4">
        @RenderBody()
    </main>

    <!-- Shared Footer -->
    <partial name="_Footer" />

    <!-- Global JS (loaded last for performance) -->
    <script src="~/js/app.min.js"></script>

    <!-- Page-specific JS (optional) -->
    @RenderSection("Scripts", required: false)
</body>
</html>

Example 2: Child View Using the Layout

<!-- Views/Products/Index.cshtml -->
@model IEnumerable<Product>
@{
    ViewData["Title"] = "All Products";
    ViewData["MetaDescription"] = "Browse our complete product catalog";
}

<h1>Product Catalog</h1>

<div class="row">
    @foreach (var product in Model)
    {
        <div class="col-md-4">
            <partial name="_ProductCard" model="product" />
        </div>
    }
</div>

@section Styles {
    <link rel="stylesheet" href="~/css/products.css" />
}

@section Scripts {
    <script src="~/js/product-filter.js"></script>
    <script>
        ProductFilter.init({ container: '.row' });
    </script>
}

Example 3: Nested Layouts (Admin vs Public)

<!-- Views/Shared/_AdminLayout.cshtml — Extends _Layout.cshtml -->
@{
    Layout = "_Layout";        // This layout WRAPS itself inside the main layout
    ViewData["Title"] = "Admin: " + ViewData["Title"];
}

<div class="d-flex">
    <!-- Admin Sidebar -->
    <nav class="admin-sidebar bg-dark text-white" style="width:280px; min-height:100vh;">
        <div class="p-3">
            <h5>⚡ Admin Panel</h5>
            <a href="/admin/dashboard" class="nav-link text-white">Dashboard</a>
            <a href="/admin/users" class="nav-link text-white">Users</a>
            <a href="/admin/products" class="nav-link text-white">Products</a>
            <a href="/admin/orders" class="nav-link text-white">Orders</a>
        </div>
    </nav>

    <!-- Admin Content Area -->
    <main class="flex-grow-1 p-4">
        @RenderBody()
    </main>
</div>
<!-- Views/Admin/Dashboard.cshtml — Uses the nested admin layout -->
@{
    Layout = "_AdminLayout";   // Uses the admin layout (which wraps inside _Layout)
    ViewData["Title"] = "Dashboard";
}

<h2>Welcome to the Admin Dashboard</h2>
<!-- This content renders inside _AdminLayout → inside _Layout -->

Example 4: _ViewStart.cshtml — The Global Default

<!-- Views/_ViewStart.cshtml -->
@{
    Layout = "_Layout";   // ALL views in /Views/ use this layout by default
}

<!-- You can also create folder-specific _ViewStart files: -->
<!-- Views/Admin/_ViewStart.cshtml -->
@{
    Layout = "_AdminLayout";  // ALL views in /Views/Admin/ use the admin layout
}

4. Sections: Required vs Optional

// In the Layout:
@RenderSection("Scripts", required: false)    // Optional: won't crash if not defined
@RenderSection("Sidebar", required: true)     // Required: crash if view doesn't define it

// Conditional rendering with IsSectionDefined:
@if (IsSectionDefined("Sidebar"))
{
    <aside class="sidebar">
        @RenderSection("Sidebar")
    </aside>
}
else
{
    <aside class="sidebar">
        <partial name="_DefaultSidebar" />
    </aside>
}

5. Layout vs Partial View vs View Component

FeatureLayoutPartial ViewView Component
PurposePage-level HTML skeletonReusable UI fragmentSelf-contained UI + Logic
Has its own controller?❌ No❌ No✅ Yes (InvokeAsync)
Can access DI?Via @injectVia @inject✅ Full DI in class
Best ForHeaders, footers, navProduct cards, formsShopping cart, recent posts
Data SourceViewData/ModelModel passed from parentOwn data from DB/service

6. Best Practices

✅ DO
  • Use _ViewStart.cshtml for default layout assignment
  • Create folder-specific _ViewStart files for different areas (Admin, Public)
  • Use required: false for optional sections like Scripts and Styles
  • Use IsSectionDefined() to provide default content when sections aren't filled
  • Use nested layouts for Admin/Public separation
❌ DON'T
  • Don't put business logic in layouts — they're for structure only
  • Don't use more than one @RenderBody() in a layout
  • Don't forget to define required sections — it causes runtime errors
  • Don't use partial views for complex components that need their own data — use View Components
  • Don't inline large CSS/JS in sections — reference external files

7. Interview Mastery

Q: "How do you structure layouts in a large enterprise application with multiple user roles?"

Architect Answer: "I use nested layouts with folder-specific _ViewStart.cshtml files. The root _Layout.cshtml handles the outermost HTML, meta tags, and shared CSS/JS bundles. Then I create role-specific layouts — _AdminLayout, _CustomerLayout, _VendorLayout — each defining their own sidebar, navigation, and permission-aware menus. Each of these sets Layout = '_Layout' to inherit the global structure. This creates a clean hierarchy: Global → Role-Specific → View, keeping hundreds of views DRY while allowing each section to have its own visual identity."

ASP.NET Core MVC Mastery
1. Core Framework
Introduction to ASP.NET Core MVC
MODULE 1: INTRODUCTION & ENVIRONMENT SETUP
Microsoft Web Stack Overview Evolution of ASP.NET Environment Setup
2. View Engine
Layouts & Partial Views in Razor
MODULE 2: .NET CORE FUNDAMENTALS
Core Concepts Project Structure Startup Flow Middleware Pipeline
MODULE 3: ASP.NET CORE BASICS
Creating Project CLI Commands wwwroot & Static Files
MODULE 4: MVC FUNDAMENTALS
MVC Architecture Dependency Injection (DI) Service Lifetimes
MODULE 5: DATA PASSING TECHNIQUES
ViewData vs ViewBag TempData ViewModel Pattern
MODULE 6: ROUTING
Conventional vs Attribute Routing Custom Constraints
MODULE 7: VIEWS & UI
Razor View Engine Layouts & Sections View Components
MODULE 8: ACTION RESULTS
ViewResult JsonResult RedirectResult
MODULE 9: HTML HELPERS
Form Helpers Custom HTML Helpers
MODULE 10: TAG HELPERS
Built-in Tag Helpers Custom Tag Helpers
MODULE 11: MODEL BINDING
FromQuery vs FromRoute Complex Binding
MODULE 12: VALIDATION
Data Annotations Remote Validation Fluent Validation
MODULE 13: STATE MANAGEMENT
Cookies & Sessions TempData
MODULE 14: FILTERS & SECURITY
Action Filters Authorize Filters Anti-forgery
MODULE 15: ENTITY FRAMEWORK CORE (DEEP DIVE)
DbContext Migrations LINQ Relationships
MODULE 16: DESIGN PATTERNS
Repository Pattern Unit of Work Clean Architecture
MODULE 17: FILE HANDLING
File Upload/Download PDF/Excel Generation
MODULE 18: ADVANCED ASP.NET CORE
Request Lifecycle Bundling & Minification Deployment
MODULE 19: PERFORMANCE & BEST PRACTICES
Caching Strategies Async Programming Secure Coding
MODULE 20: RAZOR PAGES (BONUS)
Razor Pages vs MVC
MODULE 21: REAL-WORLD PROJECTS (🔥 MUST DO)
E-Commerce Web Application Employee Management System