Chapter 22: Razor – C# Loops and Arrays
Razor: C# Loops and Arrays inside .cshtml files.
This is where your pages stop being static and start becoming truly dynamic: showing lists of products, menu items, search results, user comments, table rows, cards in a gallery, tags, pagination numbers — anything that repeats.
I’m going to explain it like we’re building a real Hyderabad food delivery website together — slowly, step by step, with lots of examples, common patterns, and the little tricks that make loops in Razor feel clean and readable.
1. Why Loops & Arrays Are So Important in Razor
In almost every real website you build:
- You have collections (arrays, lists, query results from database)
- You need to repeat HTML for each item (product card, table row, <li>, <option>, etc.)
- You often need index, conditional styling (even/odd rows, first/last item), or summaries (total price, count)
Razor + C# makes this beautifully simple — no ugly string concatenation or manual HTML building.
2. The Two Most Common Loop Types in Razor
A. @foreach — Loop over a collection (90% of cases)
|
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 |
@{ var foods = new List<string> { "Hyderabadi Biryani", "Haleem", "Pathar ka Gosht", "Irani Chai", "Osmania Biscuit", "Double Ka Meetha" }; } <h2>Top Hyderabad Foods</h2> <ul class="food-list"> @foreach (var food in foods) { <li>@food</li> } </ul> |
Output HTML (what browser sees):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
<ul class="food-list"> <li>Hyderabadi Biryani</li> <li>Haleem</li> <li>Pathar ka Gosht</li> <li>Irani Chai</li> <li>Osmania Biscuit</li> <li>Double Ka Meetha</li> </ul> |
Key points:
- var food — each item in turn
- Curly braces { … } contain the repeated HTML
- Razor automatically switches back to HTML mode after the block
B. @for — When you need index / position / step
|
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 |
@{ var foods = new List<string> { "Biryani", "Haleem", "Kebab", "Qubani ka Meetha" }; } <ol> @for (int i = 0; i < foods.Count; i++) { var rank = i + 1; var isPopular = rank <= 2; <li @(isPopular ? "class=\"popular\"" : "")> #@rank — @foods[i] @if (isPopular) { <span style="color: gold;">★ Top Pick</span> } </li> } </ol> |
→ Use @for when you need:
- Index (i)
- Step/count control
- Access by index (foods[i])
- First/last styling
3. Real-World Example – Product Cards from Database/Array
Let’s make it realistic — imagine data from a database query.
|
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 39 40 41 42 43 44 45 46 47 48 |
@{ // Simulate DB result (in real life: db.Query("SELECT * FROM Products")) var products = new[] { new { Id = 1, Name = "Hyderabadi Dum Biryani", Price = 399m, Rating = 4.8, InStock = true }, new { Id = 2, Name = "Mutton Haleem", Price = 450m, Rating = 4.6, InStock = true }, new { Id = 3, Name = "Pathar ka Gosht", Price = 520m, Rating = 4.7, InStock = false }, new { Id = 4, Name = "Double Ka Meetha", Price = 180m, Rating = 4.5, InStock = true } }; } <div class="products-grid"> @foreach (var p in products) { var stockClass = p.InStock ? "in-stock" : "out-of-stock"; var stockText = p.InStock ? "In Stock" : "Out of Stock"; <div class="product-card @stockClass"> <h3>@p.Name</h3> <p class="price">₹@p.Price.ToString("N2")</p> <p>Rating: @p.Rating ★★★★★ (@(p.Rating >= 4.5 ? "Highly Recommended" : "Good") )</p> <p class="stock">@stockText</p> @if (p.InStock) { <button class="add-to-cart">Add to Cart</button> } else { <button class="notify-me" disabled>Notify Me</button> } </div> } </div> <style> .products-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; } .product-card { border: 1px solid #ddd; padding: 15px; border-radius: 8px; } .in-stock { border-color: #28a745; } .out-of-stock { border-color: #dc3545; opacity: 0.8; } .price { font-size: 1.4em; color: #e44d26; } </style> |
→ This is typical Razor markup with loops:
- @foreach repeats the card HTML
- Variables inside (p.Name, p.Price)
- Conditionals (@if (p.InStock)) change button/content
- Dynamic classes (class=”@stockClass”)
- Formatting (ToString(“N2”) for money)
4. Bonus Patterns You’ll Use Every Day
Pattern 1: Alternating row styles (even/odd)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
@foreach (var (item, index) in items.Select((x, i) => (x, i))) { <tr class="@(index % 2 == 0 ? "even" : "odd")"> <td>@item</td> </tr> } |
Pattern 2: Show “No items” message
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
@if (products.Any()) { @foreach (var p in products) { ... } } else { <div class="alert alert-info">No products found.</div> } |
Pattern 3: First / Last item special treatment
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
@foreach (var (p, index) in products.Select((p, i) => (p, i))) { var classes = "product-card"; if (index == 0) { classes += " first"; } if (index == products.Length - 1) { classes += " last"; } <div class="@classes">...</div> } |
5. Teacher Summary – What to Remember
ASP.NET Razor – C# Loops and Arrays means:
- Use arrays / List<T> / IEnumerable<T> from DB/query/form
- @foreach — simplest and most common (no index needed)
- @for — when you need position/index/count/step
- Inside loop → normal HTML + @item.Property + @if / @(expression)
- Use LINQ helpers like .Any(), .Count(), .Select() inside @{ } blocks
- Always check for empty collections to avoid blank pages
Master these 2 loops + List<T> / var[] and you can display any repeating content beautifully.
Next class?
- Want to see pagination with loops (show 10 items, page links)?
- Or nested loops (categories → products)?
- Or how loops work with WebGrid (from earlier lessons)?
- Or jump to @model and strongly-typed collections?
Tell me — you’re building real skills here in Hyderabad! Keep going strong! 🚀🇮🇳
