Display your orders like a pro! In Part 11 of our Food Ordering System series, we implement the Shopping Cart View logic in ASP.NET Core MVC. Learn how to retrieve your stored items from the session, use LINQ to calculate the Grand Total dynamically, and pass the data to a professional cart UI. We cover the OrderController Cart Action and show you how to handle the data flow for a seamless user experience in your C# Web Application!
Step-by-Step Code Explanation
var cart = GetCart();: This line calls the helper method we wrote in Part 10. It reaches into the HttpContext Session, pulls out the JSON string, and converts it back into a list ofCartItemobjects that the view can understand.ViewBag.Total: This is where the math happens!We use the LINQ
.Sum()method to iterate through every item in the cart.It multiplies the
Priceby theQuantityfor each item and adds them all together.This total is stored in
ViewBagso we can display it prominently at the bottom of the Cart page.
return View(cart);: Finally, we pass the entire list of items (cart) to the View. This allows us to create a table or list showing the Food Name, Image, Price, and Subtotal for each item.
public IActionResult Cart()
{
// Retrieve items from session
var cart = GetCart();
// Calculate Grand Total using LINQ
ViewBag.Total = cart.Sum(c => c.Price * c.Quantity);
// Pass the list to the View
return View(cart);
}
We are moving from the backend logic to the actual User Interface (UI). This is the page where your customers can see their selected food items, adjust quantities, and see their total bill.
Step-by-Step Code Explanation
The Model:
@model List<FoodOrderingSystem.Controllers.CartItem>defines that this page expects a list of items currently in the user's shopping session.Empty Cart Logic: The code uses
@if (!Model.Any())to check if the cart is empty. If it is, it shows a friendly "Your cart is empty" message with a link back to the Menu.The Row/Column Layout:
col-md-8 (Left Side): Displays the list of food items using a
@foreachloop. Each item is wrapped in a Bootstrap "Card."col-md-4 (Right Side): Displays the Order Summary. This stays separate so the user can always see their total while scrolling through items.
Food Item Cards: Inside the loop, we display the
@item.ImageUrl,@item.Name, and@item.Price. There is also an<input>field for quantity so users can choose to order more.Action Buttons: We have included an Update button (to refresh quantities) and a Trash Icon button (to remove items from the cart).
Order Summary & Total: The total price is pulled from
@ViewBag.Total, which we calculated in the Controller. It is displayed prominently in a primary color to grab attention.
@model List<FoodOrderingSystem.Controllers.CartItem>
@{
ViewData["Title"] = "Shopping Cart";
}
<div class="container my-5">
<h2 class="mb-4"><i class="bi bi-cart3"></i> Your Cart</h2>
@if (!Model.Any())
{
<div class="alert alert-info">
Your cart is empty. <a href="/Menu">Continue shopping</a>
</div>
}
else
{
<div class="row">
<div class="col-md-8">
@foreach (var item in Model)
{
<div class="card mb-3 shadow-sm">
<div class="row g-0">
<div class="col-md-3">
<img src="@item.ImageUrl" class="img-fluid rounded-start" alt="@item.Name" style="height: 120px; object-fit: cover;">
</div>
<div class="col-md-9">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
<h5 class="card-title">@item.Name</h5>
<p class="card-text text-primary fw-bold">$@item.Price</p>
</div>
<div class="d-flex align-items-center">
<input type="number" name="quantity" value="@item.Quantity" min="1" class="form-control me-2" style="width: 70px;" />
<button type="submit" class="btn btn-outline-secondary btn-sm">Update</button>
<a href="#" class="btn btn-danger btn-sm">
<i class="bi bi-trash"></i>
</a>
</div>
</div>
</div>
</div>
</div>
}
</div>
<div class="col-md-4">
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">Order Summary</h5>
<hr />
<div class="d-flex justify-content-between mb-3">
<span>Total:</span>
<span class="h4 text-primary">$@ViewBag.Total</span>
</div>
<a href="#" class="btn btn-primary w-100 btn-lg">
Proceed to Checkout <i class="bi bi-arrow-right"></i>
</a>
</div>
</div>
</div>
</div>
}
</div>
We provide the user with full control over their order. The UpdateQuantity action is a vital piece of logic that allows a customer to change their mind—whether they want to add another pizza or reduce the number of drinks—without having to empty the entire cart.
Step-by-Step Code Explanation
[HttpPost]Attribute: This ensures the action only responds to POST requests. This is a security best practice for any action that modifies data (like changing a quantity).Parameters: The method takes two inputs:
foodItemId: To identify which specific meal is being updated.quantity: The new number of items the user wants.
The Search Logic: It calls
GetCart()to load the current session data and uses.FirstOrDefault()to find the exact item matching the ID.The Validation: The code checks
if (item != null && quantity > 0). This is a "Safety Guard" to ensure we don't update an item that doesn't exist or set a quantity to zero or a negative number.SaveCart(cart): Once the item’s quantity is updated in the list, this method saves the modified list back into the Session as a JSON string.The Refresh: Finally,
RedirectToAction("Cart")reloads the cart page so the user immediately sees the updated prices and total.
[HttpPost]
public IActionResult UpdateQuantity(int foodItemId, int quantity)
{
var cart = GetCart();
var item = cart.FirstOrDefault(c => c.FoodItemId == foodItemId);
if (item != null && quantity > 0)
{
item.Quantity = quantity;
SaveCart(cart);
}
return RedirectToAction("Cart");
}
Step-by-Step UI Code Explanation
The Form Setup:
action="/Order/UpdateQuantity": This matches the exact route of the C# Action we wrote.method="post": It uses the POST method to securely send data to the server, matching the[HttpPost]attribute in our controller.
The Hidden ID (
input type="hidden"):This is the most critical part. It stores the
@item.FoodItemIdwithout showing it to the user. When the button is clicked, the controller uses this ID to know exactly which pizza or burger needs a quantity update.
The Number Input:
type="number": Ensures the user can only type numbers.value="@item.Quantity": Automatically fills the box with the current amount in the cart.min="1": Prevents the user from accidentally setting the order to zero or a negative number.
The Update Button:
A clean
btn-outline-secondarykeeps the UI looking professional and uncluttered, allowing the "Proceed to Checkout" button to remain the main focus of the page.
<!-- Update Quantity Form inside the @foreach loop -->
<form action="/Order/UpdateQuantity" method="post" class="d-flex align-items-center me-3">
<input type="hidden" name="foodItemId" value="@item.FoodItemId" />
<input type="number" name="quantity" value="@item.Quantity" min="1" class="form-control me-2" style="width: 70px;" />
<button type="submit" class="btn btn-outline-secondary btn-sm">Update</button>
</form>
Step-by-Step Code Explanation
Parameter (
int foodItemId): The method accepts the unique ID of the food item that the user wants to delete. This ensures we remove the specific item (like a "Pepperoni Pizza") without affecting the rest of the cart.var cart = GetCart();: Just like our other actions, we start by retrieving the current list of items from the Session.The Find Logic: We use
.FirstOrDefault()to locate the specific item in our list that matches the ID provided by the user.The Removal:
The code checks if the item exists (
item != null).If found,
cart.Remove(item)deletes that specific object from our C# list.
SaveCart(cart): Crucially, we must save the updated list (the one without the deleted item) back into the Session so the change is permanent.The Redirect:
RedirectToAction("Cart")refreshes the page so the user sees their updated list and a recalculated total immediately.
public IActionResult RemoveFromCart(int foodItemId)
{
var cart = GetCart();
var item = cart.FirstOrDefault(c => c.FoodItemId == foodItemId);
if (item != null)
{
cart.Remove(item);
SaveCart(cart);
}
return RedirectToAction("Cart");
}
We finish the user experience by adding a quick and easy way to delete unwanted items. This simple UI link connects your frontend directly to the RemoveFromCart logic we just wrote.
Step-by-Step UI Code Explanation
The Anchor Tag (
<a>):Unlike the "Update" action which uses a form, the "Delete" action here uses a direct link for speed and simplicity.
href="/Order/RemoveFromCart?foodItemId=@item.FoodItemId": This sends the unique ID of the specific food item as a Query String to the controller.
Razor Syntax (
@item.FoodItemId):This dynamically pulls the correct ID for each item in your cart list. This ensures that when a user clicks the trash icon next to a "Burger," only the Burger is removed.
Bootstrap Styling:
btn btn-danger: This gives the button a bright Red color, which is the universal standard for "Delete" or "Danger" actions, helping with user intuition (UX).btn-sm: Keeps the button small and neat so it fits perfectly inside your cart item row.
The Icon (
<i class="bi bi-trash"></i>):Using Bootstrap Icons instead of text makes the UI look modern and clean. The "trash" icon is instantly recognizable by users everywhere.
<!-- Delete Item Link with Query String -->
<a href="/Order/RemoveFromCart?foodItemId=@item.FoodItemId" class="btn btn-danger btn-sm">
<i class="bi bi-trash"></i>
</a>

Comments
Post a Comment