Views, Layouts, and Partials
|
This section documents ASP.NET MVC 5.3.x, ASP.NET Web API 2.2, ASP.NET Web Pages 3, OWIN/Katana, SignalR 2,
and ASP.NET Identity 2 — all running on .NET Framework 4.8.1 — the This is not ASP.NET Core MVC. ASP.NET MVC 5 is the pre-Core, 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 documents ASP.NET MVC 5.3.x views on .NET Framework 4.8.1 — not ASP.NET Core’s Razor Pages/View Components (see Razor Syntax and Tag Helpers).
Layouts and RenderBody
A layout is a .cshtml file that wraps every view assigned to it, calling @RenderBody() exactly once where
the child view’s content belongs:
<!-- Views/Shared/_Layout.cshtml -->
<!DOCTYPE html>
<html>
<head><title>@ViewBag.Title</title></head>
<body>
@Html.Partial("_Nav")
<div class="container">@RenderBody()</div>
</body>
</html>
A view opts in with Layout = "~/Views/Shared/_Layout.cshtml"; in a code block, or inherits it from
_ViewStart.cshtml (see Razor Syntax).
Sections
@section defines a named block a layout can place anywhere with RenderSection; required: false (or
checking IsSectionDefined) makes a section optional:
<!-- in the layout -->
<head>
<title>@ViewBag.Title</title>
@RenderSection("styles", required: false)
</head>
...
@RenderSection("scripts", required: false)
<!-- in a view -->
@section scripts {
<script src="~/Scripts/product-detail.js"></script>
}
@if (IsSectionDefined("styles")) { @RenderSection("styles") }
Partial views: four ways to include one
| Helper | Behavior |
|---|---|
|
Renders synchronously into the current buffer and returns an |
|
Writes directly to the response stream ( |
|
Executes a separate child action (its own controller, its own model, its own filters) and returns its rendered output as a string, inserted into the current view. |
|
The |
@Html.Partial("_ProductSummary", Model.FeaturedProduct)
@{ Html.RenderPartial("_ProductSummary", Model.FeaturedProduct); }
@Html.Action("RecentOrders", "Orders") <!-- runs OrdersController.RecentOrders() as a child request -->
Html.Partial/Html.RenderPartial share the calling action’s model and view data — no new controller
action runs. Html.Action/Html.RenderAction invoke a full child action, which is the right tool when a
fragment (a "recently viewed" widget, a shopping-cart summary) needs its own data access independent of the
page’s main action — see donut-hole caching in
Caching and Performance, and mark such actions
[ChildActionOnly] (see Filters) so they cannot be routed to directly.
_ViewStart.cshtml chaining
_ViewStart.cshtml files run from the outermost applicable folder inward — Views/_ViewStart.cshtml first,
then an area- or folder-specific one — each able to override Layout set by the previous:
/Views/_ViewStart.cshtml # sets the site-wide default layout
/Views/Admin/_ViewStart.cshtml # overrides it for everything under Views/Admin
Display and editor templates
DisplayFor/EditorFor render a strongly typed expression through a template resolved by type name (or
[UIHint]), searched first in ~/Views/{Controller}/DisplayTemplates (or EditorTemplates), then
~/Views/Shared/DisplayTemplates:
@Html.DisplayFor(m => m.CreatedOn) <!-- resolves ~/Views/Shared/DisplayTemplates/DateTime.cshtml if present -->
@Html.EditorFor(m => m.Price)
public class Product
{
[DataType(DataType.Currency)]
[UIHint("Currency")] // forces ~/Views/Shared/EditorTemplates/Currency.cshtml
public decimal Price { get; set; }
}
<!-- Views/Shared/EditorTemplates/Currency.cshtml -->
@model decimal
@Html.TextBox("", Model.ToString("F2"), new { @class = "currency-input" })
[DataType] picks a semantic template (Currency, Date, MultilineText, …); [UIHint] names one
explicitly. See
ASP.NET
MVC Templated Helpers.
The ViewEngines collection and custom view engines
ViewEngines.Engines is the ordered list MvcHandler searches (via IViewEngine.FindView) to locate a view
for a given controller/action/master-name; RazorViewEngine and the legacy WebFormViewEngine are registered
by default:
// Global.asax.cs, Application_Start
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine()); // drop WebFormViewEngine entirely if no .aspx views remain
A custom IViewEngine/VirtualPathProviderViewEngine can change view-location conventions entirely (e.g.
feature-folder layouts) without touching controllers.
View compilation and RazorGenerator
By default, .cshtml files are compiled on first request (or via aspnet_compiler at publish time), which
means a syntax error in a view surfaces only at runtime. RazorGenerator is a community tool (a custom tool
attached to .cshtml files in Visual Studio, or an MSBuild task) that precompiles views to .cs at build time,
producing compile-time errors for view syntax mistakes and slightly faster first-request latency, at the cost
of an extra build step. See
Precompiling
Your MVC Application.
Next: HTML Helpers and Forms covers the helpers most often used inside these views.