Part 5: Making the Brand Menu Dynamic with ViewComponents
In a real-world Mobile Shop Website, you don't want to hardcode your brand names (like Apple or Samsung) in the HTML. If you add a new brand to your database, it should automatically appear in your navigation menu.
To achieve this in ASP.NET Core MVC, we use a powerful feature called ViewComponents.
Step 1: Creating the BrandsMenuViewComponent
A ViewComponent is similar to a "mini-controller." It can execute logic and fetch data from the database without needing a full MVC action.
Create a new folder in your project root named ViewComponents.
Inside that folder, create a new class file named
BrandsMenuViewComponent.cs.Paste the following code:
using Microsoft.AspNetCore.Mvc;
using MobileShop.Data;
using System.Linq;
namespace MobileShop.ViewComponents
{
public class BrandsMenuViewComponent : ViewComponent
{
private readonly ApplicationDbContext _context;
public BrandsMenuViewComponent(ApplicationDbContext context)
{
_context = context;
}
public IViewComponentResult Invoke()
{
// Fetching only active brands from the database
var brands = _context.Brands
.Where(b => b.IsActive)
.OrderBy(b => b.Name)
.ToList();
return View(brands);
}
}
}
Detailed Technical Explanation
1. Why use ViewComponent instead of Partial View?
While Partial Views are great for rendering UI, they cannot easily fetch their own data. If you put a Brand list in a Partial View, you would have to pass that list from every single Controller in your app. ViewComponents solve this by being self-contained—they fetch their own data, making them perfect for Navbars and Sidebars.
2. Dependency Injection in ViewComponents
Just like our Controllers, we use the constructor to inject the ApplicationDbContext. This allows our component to communicate with the SQL database securely and efficiently.
3. The Invoke() Method
The Invoke method is the heart of the component.
LINQ Query:
_context.Brands.Where(b => b.IsActive).ToList()ensures that if you temporarily disable a brand in your admin panel, it will instantly disappear from the public website menu.Return View: This passes the list of brands to a specific View file (which we will create in the next step).
Step 2: Designing the ViewComponent UI (Default.cshtml)
Now that we have created the logic in the backend, we need to define how the brands will look in the browser. For ViewComponents, the location of the file is extremely important.
The Folder Structure: Why Shared/Components/?
In ASP.NET Core MVC, ViewComponents follow a strict naming convention. You must create the file in this exact path:
Views/Shared/Components/BrandsMenu/Default.cshtml
Why this location?
Automatic Discovery: The MVC engine specifically looks in the
Componentsfolder for any file namedDefault.cshtml.Global Access: By placing it in the
Sharedfolder, we ensure that the Brand Menu can be called from any layout, page, or view throughout the entire website.
The Code: Views/Shared/Components/BrandsMenu/Default.cshtml
@model IEnumerable<MobileShop.Models.Brand>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">
Brands
</a>
<ul class="dropdown-menu shadow">
@foreach (var brand in Model)
{
<li>
<a class="dropdown-item"
asp-controller="Products"
asp-action="Index"
asp-route-brandId="@brand.Id">
@brand.Name.ToUpper()
</a>
</li>
}
<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item fw-bold text-primary" asp-controller="Products" asp-action="Index">
View All
</a>
</li>
</ul>
</li>
Detailed Step-by-Step Explanation
1. The Data Model (@model)
We use @model IEnumerable<Brand>. This tells the view to expect a collection of Brand objects from our BrandsMenuViewComponent. This strongly-typed approach prevents errors and enables IntelliSense while coding.
2. Dynamic Dropdown Generation
Instead of hardcoding "Apple" or "Samsung," we use a @foreach loop.
Automation: Every brand you mark as
IsActivein your database will automatically create a new<li>entry here.UI Consistency: Using
@brand.Name.ToUpper()ensures that your menu looks uniform and professional, regardless of how the name was typed into the database.
3. Tag Helpers for Navigation
We use asp-route-brandId="@brand.Id". This is crucial for SEO and Routing. It creates a clean URL that tells the controller exactly which brand the user wants to see. This makes your "Mobile Shop" easy for Google to index.
4. Dropdown Divider
The <hr class="dropdown-divider"> is a standard Bootstrap class. It helps separate the dynamic list from the "View All" option, providing a better User Experience (UX).
How to call it in _Layout.cshtml?
To see this in action, you simply replace your old hardcoded Brand <li> in the Navbar with this single line:
@await Component.InvokeAsync("BrandsMenu")
This concludes the dynamic menu implementation! By following this pattern, you’ve made your website more scalable and professional.

Comments
Post a Comment