Chapter 19: Razor Intro
Razor – Markup — that is, the HTML + Razor syntax combination that lives inside .cshtml files. This is the actual “markup” part people refer to when they say “Razor markup”.
In the previous lesson we covered what Razor is in general (the @ syntax engine). Now we’re focusing on how Razor markup actually looks and behaves — the rules, patterns, transitions between HTML and code, and the little tricks that make Razor feel magical compared to older templating systems.
I’m going to explain it slowly, like we’re building a small page together on the whiteboard, with lots of real examples.
1. Razor Markup = HTML + Embedded C# (with very smart transitions)
Razor markup is ordinary HTML that occasionally contains C# expressions or blocks marked by @.
The Razor parser is extremely clever at knowing:
- When you’re writing plain HTML
- When you start a C# expression with @
- When a C# block ends and HTML resumes
This automatic switching is the #1 reason Razor feels clean and natural.
2. The Fundamental Building Blocks of Razor Markup
A. Plain HTML — no @ needed
|
0 1 2 3 4 5 6 7 8 9 |
<div class="card"> <h2>Welcome to Hyderabad</h2> <p>This is just normal HTML.</p> </div> |
→ Razor passes this through unchanged.
B. Simple inline C# expression — single @
|
0 1 2 3 4 5 6 7 8 |
<p>Current time: @DateTime.Now</p> <p>Your name is @User.Identity.Name</p> <p>2 + 3 = @(2 + 3)</p> |
→ @ tells Razor: “the next thing is C# — evaluate it and print the result”.
Parentheses tip: Use () when the expression might be ambiguous:
- Good: @(price * qty)
- Bad (might confuse parser): @price * qty
C. Code blocks — @{ … } — multiple lines of C#
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
@{ var city = "Hyderabad"; var temp = 33; var greeting = $"Hello from {city}! It's {temp}°C today."; } <p>@greeting</p> |
→ Everything inside @{ … } is pure C# — no automatic HTML output unless you explicitly print something.
D. Transition back to HTML is automatic
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@{ var isWeekend = DateTime.Today.DayOfWeek == DayOfWeek.Saturday || DateTime.Today.DayOfWeek == DayOfWeek.Sunday; } <div class="alert @(isWeekend ? "alert-success" : "alert-info")"> @if (isWeekend) { <strong>Weekend vibes! 🎉</strong> <p>Enjoy your day off in Hyderabad!</p> } else { <strong>Working day</strong> <p>Keep hustling!</p> } </div> |
→ Razor knows that after @if { … } the <strong> is HTML again — no need to close anything manually.
3. The Tricky Cases — When Razor Needs Help Knowing What You Want
Case 1: You want literal text inside a code block (rare but important)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
@{ if (isAdmin) { @:You are an administrator! <text>Welcome to the secret area.</text> } } |
- @: → tells Razor “this line is literal HTML/text — output it as-is”
- <text>…</text> → same thing, but for multiple lines (no visible tag in output)
Case 2: Email addresses or Twitter handles — don’t let @ start code!
|
0 1 2 3 4 5 6 7 |
<p>Contact me at someone@example.com</p> <p>Follow @webliance on X</p> |
→ Razor sees @webliance and thinks it’s C# → error!
Fixes (choose one):
|
0 1 2 3 4 5 6 7 8 |
<p>Follow @@webliance on X</p> <!-- double @@ becomes single @ --> <p>Follow <text>@webliance</text> on X</p> <!-- <text> escapes --> <p>Email: someone&#64;example.com</p> <!-- HTML entity --> |
Most common: just use @@ — it’s short and clean.
4. Full Realistic Page Example – Putting It All Together
Menu.cshtml — a small navigation component using Razor markup
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
@{ var pages = new[] { new { Path = "/", Title = "Home", Icon = "🏠" }, new { Path = "/Products", Title = "Products", Icon = "🛒" }, new { Path = "/About", Title = "About Us", Icon = "ℹ️" }, new { Path = "/Contact", Title = "Contact", Icon = "✉️" } }; var currentPath = Context.Request.Path.Value; } <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="/">Webliance Shop</a> <div class="collapse navbar-collapse"> <ul class="navbar-nav ms-auto"> @foreach (var page in pages) { var isActive = currentPath.Equals(page.Path, StringComparison.OrdinalIgnoreCase) || (currentPath.StartsWith(page.Path + "/") && page.Path != "/"); <li class="nav-item"> <a class="nav-link @(isActive ? "active" : "")" href="@page.Path"> @page.Icon @page.Title </a> </li> } </ul> </div> </div> </nav> |
→ This is classic Razor markup:
- C# block at top (data preparation)
- @foreach loop inside HTML
- Inline @(isActive ? …) ternary
- @page.Icon and @page.Title printing values
- Clean Bootstrap HTML structure
5. Razor Markup vs Older Styles – Quick Comparison Table
| Style | Example Markup | Readability | Control over HTML |
|---|---|---|---|
| Classic ASP | <% if (x>0) { %> <b>Yes</b> <% } %> | Poor | Good |
| ASP.NET Web Forms | <asp:Label runat=”server” Text='<%# Eval(“Name”) %>’ /> | Medium | Limited |
| PHP | <p>Hello <?php echo $name; ?></p> | Medium | Good |
| Razor (modern) | <p>Hello @name</p> @if (…) { <b>Yes</b> } | Excellent | Full |
Razor wins on cleanliness and full HTML control.
6. Teacher Closing Thoughts
ASP.NET Razor Markup is:
- HTML-first — write normal HTML, sprinkle @ where you need dynamic content
- Intelligent transitions — knows when C# ends and HTML resumes
- Minimal punctuation — no <% %> noise, no mandatory parentheses most times
- Very forgiving for front-end developers — feels like enhanced HTML
- The foundation of Razor Pages, MVC Views, and Blazor components today
Master these patterns (@expression, @{ code }, @if / @foreach, Page.Title, RenderBody, @@ escape) and you can write beautiful, maintainable .NET web pages.
Homework / next step?
- Want to see Razor markup in ASP.NET Core Razor Pages (with @page directive, @model, @using)?
- Or compare Razor vs JSX (React) syntax side-by-side?
- Or build a small Razor-based contact form together?
Just tell me — we’re going deep into modern .NET from Hyderabad! 🚀🇮🇳
