Razor Syntax
|
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 the Razor view engine as it ships with ASP.NET MVC 5.3.x / Web Pages 3 on .NET Framework 4.8.1 — not ASP.NET Core’s Razor, which adds Tag Helpers and Blazor component syntax on top of the same expression language (see Razor Syntax and Tag Helpers).
Where Razor came from
Razor shipped in January 2011 as part of MVC 3, alongside ASP.NET Web Pages 1 — a lightweight,
non-MVC way to build .cshtml sites. It replaced the original MVC 1/2 WebForms view engine
(.aspx/.ascx views with <%= %>/<%: %> code-nuggets and a ViewPage base class inherited from Web
Forms), which was verbose, easy to mis-encode, and dragged in Web Forms concepts (the page directive, control
parsing) that MVC’s action/view model did not need. Razor was designed from scratch for view templates: a
minimal-punctuation syntax the parser can distinguish from literal markup by context, HTML-encoding by default,
and no dependency on the Web Forms control tree.
Implicit and explicit expressions
<p>Hello, @Model.UserName!</p> <!-- implicit expression: @ + a single identifier/member chain -->
<p>Total: @(Model.Price * Model.Quantity)</p> <!-- explicit expression: @( ... ) for anything the parser can't disambiguate -->
Code blocks
@{
var greeting = "Welcome back";
ViewBag.Title = "Home";
}
<h1>@greeting, @Model.UserName</h1>
@: and <text>
Inside a code block, a line of literal text needs an explicit marker so Razor doesn’t try to parse it as C#:
@foreach (var item in Model.Items)
{
@:Item: @item.Name <!-- single line of literal markup -->
<text>Qty: @item.Quantity</text> <!-- multi-token literal run without wrapping HTML -->
}
Automatic HTML encoding and Html.Raw
Every @-expression is HTML-encoded by default, which is what makes Razor safe against reflected XSS by
default (see Security Hardening):
<p>@Model.Comment</p> <!-- "<script>" is encoded to "<script>" -->
<div>@Html.Raw(Model.TrustedHtml)</div> <!-- opt out ONLY for content you generated/sanitized yourself -->
Html.Raw must never be used on user-supplied input without sanitizing it first — it is the single most common
source of stored/reflected XSS in MVC 5 codebases.
@model, @using, @inherits, @functions, @helper
@model MyApp.Models.ProductViewModel
@using MyApp.Helpers
@inherits System.Web.Mvc.WebViewPage<MyApp.Models.ProductViewModel> <!-- rarely needed; @model implies this -->
<h1>@Model.Name</h1>
@helper Star(int filled) <!-- an inline, reusable markup-producing helper, scoped to this view -->
{
for (int i = 0; i < 5; i++) { <span class="@(i < filled ? "on" : "off")">*</span> }
}
@Star(Model.Rating)
@functions {
// C# members (not markup-producing) usable elsewhere in the same view
string FormatPrice(decimal p) => p.ToString("C");
}
<p>@FormatPrice(Model.Price)</p>
@model is sugar for @inherits System.Web.Mvc.WebViewPage<T>, giving the view a strongly typed Model.
_ViewStart.cshtml
Views/_ViewStart.cshtml (and an area-local Views/{Area}/_ViewStart.cshtml) runs before every view in its
folder and below, and conventionally sets the shared Layout:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Views/web.config namespaces
Namespaces listed in Views/web.config under <system.web.webPages.razor><pages><namespaces> are available to
every view without an explicit @using (see
Getting Started for the full snippet) — System.Web.Mvc.Html (the
HTML helpers, see HTML Helpers and Forms) is imported this way
by default.
ASP.NET Web Pages 3: the third framework of this era
ASP.NET Web Pages is .cshtml Razor without MVC — a page-per-file model closer to classic ASP or PHP
than to MVC’s controller/action separation, aimed at simple sites. It shares the Razor parser and
Microsoft.AspNet.WebPages runtime with MVC (see
Getting Started) but has its own conventions:
@{
// default.cshtml -- the file itself is the "action"
Page.Title = "Home";
}
<h1>@Page.Title</h1>
@RenderPage("~/_nav.cshtml") <!-- Web Pages' equivalent of a partial -->
-
An
App_Start/_AppStart.cshtmlruns once at startup, analogous to MVC’sApplication_Start. -
WebSecurity(Microsoft.Web.WebPages.OAuth/WebMatrix.WebData) provided Web Pages' own membership and OAuth login support, parallel to (and predating) ASP.NET Identity — see Authentication, Identity, and OWIN. -
Web Pages is rarely chosen for new work even within the MVC 5 era; it is documented here because it explains why
Microsoft.AspNet.WebPagesappears as a dependency of every MVC 5 project even when no.cshtmlfile is ever rendered outside theViewsfolder.
Next: Views, Layouts, and Partials builds on this syntax to cover layouts, sections, and reusable view fragments.