Introduction
Views turn C# data into HTML the browser understands. In ASP.NET Core MVC, views are Razor files (.cshtml) — HTML with embedded C# using the @ symbol. Controllers from Article 5 choose what to show; views define how it looks.
This lesson builds the ShopNest Restaurant Menu — categories, dishes, prices, dietary tags — using Razor expressions, loops, conditionals, layouts, and every way to pass data from controller to view.
After this article you will
- Write Razor syntax: expressions, code blocks,
@if,@foreach - Pass data via strongly-typed models, ViewBag, ViewData, TempData
- Understand _Layout, _ViewStart, _ViewImports
- Render a full restaurant menu from a collection
Prerequisites
- Article 6 — Routing
- Basic HTML and C#
Razor syntax essentials
Level 1 — Analogy
Razor is a merge template — like a restaurant menu Word doc with mail-merge fields. Static text stays HTML; @item.Name inserts live data from the kitchen (controller).
Level 2 — Technical
@* Comment — not sent to browser *@
@model IEnumerable<MenuItem>
<h1>ShopNest Bistro — Today's Menu</h1>
@foreach (var item in Model)
{
<div class="menu-row">
<h3>@item.Name</h3>
<p>@item.Description</p>
<span class="price">₹@item.Price.ToString("N0")</span>
@if (item.IsVeg)
{
<span class="badge bg-success">Veg</span>
}
</div>
}
Implicit vs explicit expressions: @DateTime.Now.Year works; complex expressions need parentheses: @(user.IsAdmin ? "Admin" : "Guest").
Code blocks: @{ var total = Model.Count(); } runs C# without outputting text.
Passing data to views
| Mechanism | Type-safe? | Best for |
|---|---|---|
@model MenuPageViewModel | Yes | Primary pattern — always prefer this |
ViewBag.Title = "Menu" | No (dynamic) | Page title, minor extras |
ViewData["Title"] | No (object dictionary) | Same as ViewBag, string keys |
TempData["Message"] | No | Flash message after redirect (PRG) |
// MenuController.cs
public IActionResult Index()
{
var vm = new MenuPageViewModel
{
RestaurantName = "ShopNest Bistro",
Items = _menuService.GetTodayMenu()
};
ViewBag.LastUpdated = DateTime.Now;
return View(vm);
}
Layout, _ViewStart, _ViewImports
@* Views/Shared/_Layout.cshtml *@
<!DOCTYPE html>
<html>
<head><title>@ViewData["Title"] - ShopNest</title></head>
<body>
<header>... nav ...</header>
<main>@RenderBody()</main>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
_ViewStart.cshtml— setsLayout = "_Layout"for all views in folder_ViewImports.cshtml— common@using,@addTagHelper@section Scripts { }— page-specific JS at bottom of layout
HTML Helpers vs Tag Helpers (preview)
Legacy: @Html.ActionLink("Menu", "Index", "Menu"). Modern (preferred): <a asp-controller="Menu" asp-action="Index">Menu</a>. Full Tag Helper guide in Article 11.
Hands-on — Restaurant menu
- Create
MenuItemmodel: Name, Description, Price, Category, IsVeg. MenuController.Indexreturns list grouped by category.- View uses
@foreachwith Bootstrap cards. - Add filter tabs (All / Veg / Non-Veg) with
@if.
@model MenuPageViewModel
@{
ViewData["Title"] = Model.RestaurantName;
var grouped = Model.Items.GroupBy(i => i.Category);
}
@foreach (var group in grouped)
{
<h2 class="mt-4">@group.Key</h2>
<div class="row">
@foreach (var item in group)
{
<div class="col-md-4 mb-3">
<div class="card">
<div class="card-body">
<h5>@item.Name</h5>
<p>₹@item.Price</p>
</div>
</div>
</div>
}
</div>
}
Interview questions
Q1: What is Razor?
A: Syntax for embedding C# in HTML views; compiled to C# classes at runtime/build.
Q2: ViewBag vs ViewData vs TempData?
A: ViewBag/ViewData for same-request data; TempData survives one redirect via session cookie.
Q3: What is @RenderBody()?
A: Placeholder in layout where individual view content is injected.
Q4: Strongly-typed view benefit?
A: Compile-time checking and IntelliSense via @model directive.
Summary
- Razor mixes HTML and C# with
@syntax - Prefer strongly-typed
@modelover ViewBag - Layouts and sections keep ShopNest UI consistent
- Restaurant menu demo shows loops, conditionals, grouping
Previous: Routing
Next: Layouts, Partial Views and View Components
FAQ
Can I use JavaScript frameworks instead of Razor?
Yes — SPA with React/Vue uses Razor minimally. Traditional ShopNest MVC pages still rely heavily on Razor for SEO-friendly server-rendered HTML.