Section 6 of 6
Areas
đ¯ What You'll Learn
- What areas are and why use them
- Creating area structure
- Routing with areas
- Area attribute routing
- URL generation for areas
- Best practices
What are Areas?
Areas organize large MVC applications into logical sections, each with its own controllers, views, and models.
Why Use Areas?
- Organization: Separate admin, customer, and public sections
- Team collaboration: Different teams work on different areas
- Modularity: Each area is self-contained
- Scalability: Manage large applications
Example Areas
Text
InvenTrack/
âââ Areas/
â âââ Admin/ â Admin dashboard
â â âââ Controllers/
â â âââ Views/
â â âââ Models/
â âââ Customer/ â Customer portal
â â âââ Controllers/
â â âââ Views/
â â âââ Models/
â âââ Reports/ â Reporting section
â âââ Controllers/
â âââ Views/
â âââ Models/
âââ Controllers/ â Default (no area)
Creating an Area
1. Create Folder Structure
Folder Structure
Text
Areas/
âââ Admin/
âââ Controllers/
â âââ DashboardController.cs
âââ Views/
â âââ Dashboard/
â â âââ Index.cshtml
â âââ _ViewStart.cshtml
âââ Models/
2. Add [Area] Attribute
Areas/Admin/Controllers/DashboardController.cs
C#
[Area("Admin")]
public class DashboardController : Controller
{
public IActionResult Index()
{
return View();
}
}
3. Configure Routing
Program.cs
C#
app.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
âšī¸ {area:exists}
The {area:exists} constraint ensures the route only matches if the
area exists. Area routes should come before default routes.
Routing with Areas
URL Pattern
Area URLs
Text
/Admin/Dashboard/Index
â â â
Area Controller Action
Conventional Routing
Program.cs
C#
// Area route (must come first)
app.MapControllerRoute(
name: "admin",
pattern: "Admin/{controller=Dashboard}/{action=Index}/{id?}",
defaults: new { area = "Admin" });
// Default route
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Attribute Routing with Areas
Using [Area] Attribute
C#
[Area("Admin")]
[Route("admin/[controller]/[action]")]
public class ProductsController : Controller
{
// GET /admin/products/index
public IActionResult Index() { }
// GET /admin/products/create
public IActionResult Create() { }
}
Using [area] Token
Token Replacement
C#
[Area("Admin")]
[Route("[area]/[controller]/[action]")]
public class DashboardController : Controller
{
// GET /admin/dashboard/index
public IActionResult Index() { }
}
URL Generation for Areas
Url.Action() with Area
Generate Area URLs
C#
// Link to area controller
var url = Url.Action("Index", "Dashboard", new { area = "Admin" });
// â /Admin/Dashboard/Index
// Link to default (no area)
var url = Url.Action("Index", "Home", new { area = "" });
// â /Home/Index
In Razor Views
Views/Shared/_Layout.cshtml
HTML
<!-- Link to Admin area -->
<a asp-area="Admin" asp-controller="Dashboard" asp-action="Index">
Admin Dashboard
</a>
<!-- Link to default (no area) -->
<a asp-area="" asp-controller="Home" asp-action="Index">
Home
</a>
RedirectToAction() with Area
Redirects
C#
// Redirect to area
return RedirectToAction("Index", "Dashboard", new { area = "Admin" });
// Redirect to default
return RedirectToAction("Index", "Home", new { area = "" });
Complete InvenTrack Example
Folder Structure
InvenTrack Areas
Text
InvenTrack/
âââ Areas/
â âââ Admin/
â â âââ Controllers/
â â â âââ DashboardController.cs
â â â âââ ProductsController.cs
â â â âââ UsersController.cs
â â âââ Views/
â â âââ Dashboard/
â â â âââ Index.cshtml
â â âââ Products/
â â â âââ Index.cshtml
â â â âââ Create.cshtml
â â âââ _ViewStart.cshtml
â âââ Reports/
â âââ Controllers/
â â âââ SalesController.cs
â â âââ InventoryController.cs
â âââ Views/
âââ Controllers/
âââ HomeController.cs
Admin Area Controller
Areas/Admin/Controllers/ProductsController.cs
C#
[Area("Admin")]
[Route("[area]/[controller]/[action]")]
[Authorize(Roles = "Admin")]
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
// GET /admin/products/index
public async Task<IActionResult> Index()
{
var products = await _productService.GetAllAsync();
return View(products);
}
// GET /admin/products/create
public IActionResult Create()
{
return View();
}
// POST /admin/products/create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ProductViewModel model)
{
if (!ModelState.IsValid)
return View(model);
await _productService.CreateAsync(model);
// Redirect to Index in same area
return RedirectToAction(nameof(Index));
}
}
Reports Area Controller
Areas/Reports/Controllers/SalesController.cs
C#
[Area("Reports")]
[Route("[area]/[controller]/[action]")]
public class SalesController : Controller
{
// GET /reports/sales/monthly
public IActionResult Monthly()
{
return View();
}
// GET /reports/sales/yearly
public IActionResult Yearly()
{
return View();
}
}
Program.cs Configuration
Program.cs
C#
builder.Services.AddControllersWithViews();
var app = builder.Build();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// Area routes (must come first)
app.MapControllerRoute(
name: "areas",
pattern: "{area:exists}/{controller=Dashboard}/{action=Index}/{id?}");
// Default route
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Navigation Menu
Views/Shared/_Layout.cshtml
HTML
<nav>
<!-- Default area -->
<a asp-area="" asp-controller="Home" asp-action="Index">Home</a>
<!-- Admin area -->
<a asp-area="Admin" asp-controller="Dashboard" asp-action="Index">
Admin Dashboard
</a>
<a asp-area="Admin" asp-controller="Products" asp-action="Index">
Manage Products
</a>
<!-- Reports area -->
<a asp-area="Reports" asp-controller="Sales" asp-action="Monthly">
Sales Reports
</a>
</nav>
Best Practices
- Logical grouping: Group related functionality (Admin, Reports, etc.)
- Area routes first: Register area routes before default routes
- Use [Area] attribute: Always decorate area controllers
- Consistent naming: Use PascalCase for area names
- Authorization: Apply area-wide authorization
- Shared layouts: Each area can have its own layout
- URL generation: Always specify area in links
- Empty area: Use
area = ""for default
When to Use Areas
| Use Areas | Don't Use Areas |
|---|---|
| Large applications | Small applications |
| Multiple logical sections | Single-purpose apps |
| Team collaboration | Solo projects |
| Admin vs public sections | Simple CRUD apps |
| Modular architecture | APIs (use versioning instead) |
Key Takeaways
- Areas: Organize large MVC apps into logical sections
- [Area] attribute: Required on area controllers
- Folder structure: Areas/[AreaName]/Controllers/Views/Models
- Routing:
{area:exists}/{controller}/{action} - URL generation: Include
areain route values - Area routes first: Register before default routes
- [area] token: Use in attribute routes
- Empty area:
area = ""for default - Use cases: Admin panels, reports, customer portals
đ Part VII Complete!
Congratulations! You've completed Part VII: Routing. You now understand:
- â Endpoint routing architecture
- â Conventional vs attribute routing
- â Route parameters (required, optional, catch-all)
- â Route constraints (int, guid, regex, custom)
- â URL generation (Url.Action, CreatedAtAction, LinkGenerator)
- â Areas for organizing large applications
You now have complete control over routing in ASP.NET Core! This knowledge is essential for building well-structured, maintainable applications. Keep up the great work! đ