Razor Views and Layouts
Razor is ASP.NET Core's templating language: C# and HTML in one .cshtml file, with
@ switching between them. You already know the two hard parts (C# and HTML); this lesson is the
glue β and the one security property you must not break.
Syntax and structure
@Model.CustomerName outputs a value; @if, @foreach, and @{ ... } blocks run code. The
@model OrderListViewModel directive at the top makes Model strongly typed β you get
IntelliSense and (with runtime compilation off, the default) build-time checking. Razor is smart
about email addresses and transitions, but when it guesses wrong, be explicit: @(order.Id) or
the text tag for literal output inside code blocks.
The page skeleton lives in a layout (_Layout.cshtml): the <html> shell, nav bar, Bootstrap
and jQuery includes. Each view supplies its content where the layout calls @RenderBody().
Sections handle per-view placement in the layout β the standard one is a scripts section at
the bottom so page-specific JavaScript loads after jQuery:
@section scripts {
<script src="~/js/orders-edit.js"></script>
}
Declare it in the layout with @RenderSection("scripts", required: false). The _ViewStart.cshtml
file assigns the default layout so individual views don't have to.
Partials: the reuse unit
A partial view (_OrderRow.cshtml β underscore prefix by convention) renders a fragment with
no layout. Use partials for repeated UI (an address block, a table row template) and β critically
for Module 3's jQuery lesson β as the response to AJAX calls: the controller returns
PartialView("_OrderRow", vm) and jQuery injects the HTML. One discipline: pass the partial an
explicit model (<partial name="_Address" model="Model.BillingAddress" />); partials that
silently read the parent's model or ViewBag are the views hardest to reuse.
Tag helpers, and encoding by default
Tag helpers are the default way to generate form-and-link markup from your model:
<input asp-for="Name" />, <span asp-validation-for="Name">, <a asp-action="Index">. They
look like HTML, so designers and diff tools cope, and asp-for emits the exact name attributes
model binding expects plus the data-val-* attributes validation needs β which hand-written
<input> tags get subtly wrong. The older HTML helpers (@Html.TextBoxFor(m => m.Name),
@Html.ActionLink(...)) still exist and produce the same output; you'll read them fluently in
older views and in Kendo's fluent API, but write tag helpers in new code.
Finally, the security property: Razor HTML-encodes everything it outputs. If
Model.Comment contains <script>, the page shows the literal text β that's your default XSS
defense, and it's on without you doing anything. The escape hatch, Html.Raw(...), turns it
off. Treat every Html.Raw in review as guilty until proven innocent: it's only safe for content
your own code generated or sanitized, never for anything a user typed. In a public-facing agency
app, stored XSS through a "comments" field is a career-limiting bug.