Master the art of building a dynamic Menu Page in ASP.NET Core MVC! In Part 8 of our Online Food Ordering System series, we go beyond a simple list to create a fully categorized food menu. Learn how to fetch data from SQL Server using Entity Framework Core, group items by Categories (Pizza, Burgers, Drinks), and implement a clean, responsive UI with Bootstrap 5. We cover LINQ queries for efficient data loading and show you how to build an 'Add to Cart' flow that works seamlessly. Elevate your C# Web Development skills and build a professional-grade menu today!
This MenuController is the core of your ordering system. While the HomeController only showed a few featured items, this controller handles the Full Menu and adds the ability to Filter by Category (like showing only "Pizza" or "Burgers").
Step-by-Step Explanation
Dependency Injection: Just like before, we bring in
ApplicationDbContext. This is your direct link to the SQL Server database.int? categoryIdParameter: TheIndexmethod now accepts an optional ID. If a user clicks "Pizza," thecategoryIdwill be 1. If they just open the menu, it will benull(showing everything).ViewBag.Categories: We fetch all categories from the database and store them inViewBag. This allows us to build a sidebar or navigation menu in the View so users can switch between food types..Include(f => f.Category): This is an Eager Loading command. It tells Entity Framework to join theFoodItemstable with theCategoriestable so we can display the category name next to the food item.The Filtering Logic:
f.IsAvailable: Ensures we don't show items that are out of stock.(categoryId == null || f.CategoryId == categoryId): This is a clever "either/or" check. If no category is selected (null), it returns everything. If an ID is provided, it only returns items matching that specific category.
using Microsoft.AspNetCore.Mvc;
using FoodOrderingSystem.Models;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace FoodOrderingSystem.Controllers
{
public class MenuController : Controller
{
private readonly ApplicationDbContext _context;
public MenuController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Index(int? categoryId)
{
// Get categories for the filter sidebar
var categories = _context.Categories.ToList();
ViewBag.Categories = categories;
// Fetch items with optional category filtering
var foodItems = _context.FoodItems
.Include(f => f.Category)
.Where(f => f.IsAvailable && (categoryId == null || f.CategoryId == categoryId))
.ToList();
return View(foodItems);
}
}
}
This Index.cshtml view for the Menu is a masterpiece of functional UI. It doesn't just list food; it provides a filtered, organized browsing experience that is essential for any professional E-commerce application.
Code Explanation
@foreach (var cat in ViewBag.Categories): This loop creates the Category Filter Bar. It dynamically generates buttons based on the categories in your database (Pizza, Burgers, etc.). Each button links back to the same page but passes acategoryIdto the controller.The Grid System (
col-md-3): In the Home Page, we usedcol-md-4(3 items per row). Here, we usecol-md-3to show 4 items per row. This allows the user to see more of the menu at once, which is better for browsing.@item.Category.NameBadge: Because we used.Include(f => f.Category)in the controller, we can now display a small badge showing exactly which category the food belongs to.Hidden Input Form: Unlike a simple link, using a small form with an
<input type="hidden">is a more robust way to send thefoodItemIdto the AddToCart action.Responsive Styling: The use of
h-100 shadowon the Bootstrap cards ensures that all cards are the same height and have a professional "pop" off the page.
@model List<FoodItem>
@{
ViewData["Title"] = "Menu";
}
<div class="container my-5">
<h2 class="text-center mb-4">Our Menu</h2>
<!-- Category Filter Bar -->
<div class="row mb-4">
<div class="col-md-12 text-center">
<a href="/Menu" class="btn btn-outline-primary me-2">All</a>
@foreach (var cat in ViewBag.Categories)
{
<a href="/Menu?categoryId=@cat.Id" class="btn btn-outline-primary me-2">@cat.Name</a>
}
</div>
</div>
<!-- Food Items Grid -->
<div class="row">
@foreach (var item in Model)
{
<div class="col-md-3 mb-4">
<div class="card food-card h-100 shadow">
<img src="@item.ImageUrl" class="card-img-top" alt="@item.Name" style="height: 180px; object-fit: cover;">
<div class="card-body">
<span class="badge bg-secondary">@item.Category.Name</span>
<h5 class="card-title mt-2">@item.Name</h5>
<p class="card-text text-muted small">@item.Description</p>
<div class="d-flex justify-content-between align-items-center mt-3">
<span class="h5 mb-0 text-primary">$@item.Price</span>
<form action="/Order/AddToCart" method="get" class="d-inline">
<input type="hidden" name="foodItemId" value="@item.Id" />
<button type="submit" class="btn btn-primary btn-sm">
<i class="bi bi-cart-plus"></i> Add
</button>
</form>
</div>
</div>
</div>
</div>
}
</div>
</div>

Comments
Post a Comment