liveBook · Manning

Layout

As explained in ASP.NET Core in Action, 3e

A Razor layout is a shared Razor template that defines common page structure and renders the content of individual pages within it.

A Razor layout supplies the HTML shared by several pages, such as the document structure, header, footer, and CSS links. Razor combines it with an individual view to produce the HTML sent to the browser. Keeping shared markup in one place avoids editing every page when that markup changes. section 17.4 section 13.1.3

A layout is a Razor template, not a standalone Razor Page: it cannot be rendered directly, does not take part in routing, and has no @page directive. Layouts commonly live in Pages/Shared; _Layout.cshtml is the conventional name for a base layout. Every layout must call @RenderBody() where the child view’s content should appear. section 17.4 section 17.4.1

Listing 17.7 A basic _Layout.cshtml file calling RenderBody
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewData["Title"]</title>                 #1
    <link rel="stylesheet" href="~/css/site.css" />   #2
</head>
<body>
    @RenderBody()                                     #3
</body>
</html>
#1 ViewData is the standard mechanism for passing data to a layout from a view.
#2 Elements common to every page, such as your CSS, are typically found in the layout.
#3 Tells the templating engine where to insert the child view’s content

This minimal _Layout.cshtml puts shared document markup and a CSS link around @RenderBody(). Its <title> reads ViewData set by the view. section 17.4.1

A view can choose its layout with @{ Layout = "_Layout"; }. It can also set ViewData["Title"] so the layout can use the page-specific title. For a common default, _ViewStart.cshtml can set the layout before each Razor Page runs; it does not run for layouts or partial views. section 17.4.1 section 17.5

Use sections when a view must supply content somewhere besides @RenderBody(). Define content with @section in the view and place it with @RenderSection() in the layout. A required section must be supplied; an optional one can be omitted. An optional Scripts section, for example, lets only pages that need extra JavaScript include it. section 17.4.2

Listing 17.11 Rendering a section in a layout file, _TwoColumn.cshtml
@{
    Layout = "_Layout";                        #1
}
<div class="main-content">
    @RenderBody()                              #2
</div>
<div class="side-bar">
    @RenderSection("Sidebar", required: true)  #3
</div>
@RenderSection("Scripts", required: false)     #4

The two-column layout places the main content with @RenderBody(), requires Sidebar, permits Scripts to be omitted, and itself selects a parent layout. section 17.4.2

An application can use different layouts for different areas and nest layouts to keep site-wide markup in a base layout. For example, product pages might use three columns while checkout uses one. A shared login partial can also be rendered from the main layout, while Identity pages use _ViewStart.cshtml to select that same base layout. section 17.4.1 section 23.4.3

How ASP.NET Core in Action, 3e covers it

How deep it goes
Works through layout selection, RenderBody, shared ViewData, nested layouts, and required or optional sections.
Examples
Uses a minimal _Layout.cshtml, a two-column sidebar layout, differing product and checkout layouts, and an Identity login partial.
What it assumes
Starts with HTML document elements and introduces layouts as Razor templates; uses Razor views and code blocks to show selection.
What you can do after
Build it from scratch: create a shared Razor layout, select it for views, and place page content and optional sections.
How it connects
Connects Razor views, Razor Pages, ViewData, _ViewStart.cshtml, sections, and partial views.

Also explained in

Compare how 7 books explain layout →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.