ASP.NET Core MVC позволяет организовать приложение в виде областей, где каждая область представляет какой-то свой сегмент приложения. Например, одна область может отвечать за функции администрирования, другая - за управление учетными записями и т.д. Фактически каждая область представляет собой мини-проект, имеет свою собственную структуру каталогов. Это позволяет разрабатывать и тестировать код для каждой области отдельно независимо от других областей.
Возьмем простейший проект ASP.NET Core по типу Empty и сначала добавим в нее папку Controllers, а в нее поместим примитивный контроллер HomeController со следующим кодом:
using Microsoft.AspNetCore.Mvc; namespace MvcApp.Controllers { public class HomeController : Controller { public string Index() => "HomeController вне области"; } }
Этот контроллер не принадлежит никакой области.
Теперь добавим область. Как правило, области помещаются в отдельную папку. Поэтому добавим в проект новую папку, которую назовем Areas. В ней будут росполагаться области.
Затем в папку Areas добавим каталог под названием Account. То есть у нас будет область под названием Account.
И далее в папке Areas/Account создадим подкаталоги Controllers и Views. В итоге проект будет выглядеть так:
Затем в папку Controllers добавим новый контроллер HomeController:
using Microsoft.AspNetCore.Mvc; namespace MvcApp.Areas.Account.Controllers { [Area("Account")] public class HomeController : Controller { public IActionResult Index() { return View(); } } }
Для ассоциации контроллера с определенной областью к этому контроллеру применяется атрибут Area, в который передается название области. Без этого атрибута контроллер не будет принадлежать области Account.
Далее в папку Areas/Account/Views добавим подкаталог Home - для представлений нового контроллера. И затем в этот подкаталог поместим представление Index.cshtml с одной строкой:
<h2>HomeController из области Account</h2>
Вообще поиск представления для контроллера из области ведется по следующим путям:
/Areas/Account/Views/Home/
/Areas/Account/Views/Shared/
/Views/Shared/
Соответственно все три выше указанные папки мы могли бы использовать для хранения представления Index.cshtml для контроллера из области Account.
Таким образом, проект теперь выглядит так:
Но пока эта область совершенно неактивна. Мы никак не можем к ней обратиться. И теперь добавим в приложение поддержку этой области. Для этого изменим код в файле Program.cs следующим образом:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); // добавляем поддержку контроллеров, которые располагаются в области app.MapControllerRoute( name: "Account", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); // добавляем поддержку для контроллеров, которые располагаются вне области app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Для сопоставления с областью в первом маршруте определен сегмент area
. Ограничение exists
используется для того, чтобы маршрут сопоставлялся только с теми областями, которые определены в приложении.
И теперь мы сможем обращаться к области с запросом http://localhost:xxxx/Account:
Если же в запросе не использован префикс "Account", то обращение будет производиться к контроллеру HomeController, который расположен вне области
В примере выше определялся маршрут для всех областей. С помощью метода MapAreaControllerRoute() можно указать маршрут для конкретной области:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); // маршрут для области account app.MapAreaControllerRoute( name: "account_area", areaName: "account", pattern: "profile/{controller=Home}/{action=Index}/{id?}"); // добавляем поддержку для контроллеров, которые располагаются вне области app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Метод MapAreaControllerRoute()
принимает три обязательных параметра: имя маршрута, имя области (areaName) и шаблон маршрута.
Причем шаблон маршрута начинается с префикса области: "store/{controller=Home}/{action=Index}/{id?}". Обратите внимание, что в данном случае для обращения к области Account путь запроса должен начинаться с "profile":
Подобным образом можно определить маршруты для нескольких областей:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); // маршрут для области account app.MapAreaControllerRoute( name: "account_area", areaName: "account", pattern: "profile/{controller=Home}/{action=Index}/{id?}"); // маршрут для области service app.MapAreaControllerRoute( name: "service_area", areaName:"service", pattern: "service/{controller=Home}/{action=Index}/{id?}"); // добавляем поддержку для контроллеров, которые располагаются вне области app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Также мы могли бы задать маршрут через атрибут маршрутизации, в котором параметр area
представлял бы область:
using Microsoft.AspNetCore.Mvc; namespace MvcApp.Areas.Account.Controllers { [Area("Account")] public class HomeController : Controller { [Route("{area}")] [Route("{area}/{controller}")] [Route("{area}/{controller}/{action}")] public IActionResult Index() { return View(); } } }
Для обращения к такому методу Index мы можем использовать три адреса: http://localhost:xxxx/Account, http://localhost:xxxx/Account/Home и http://localhost:xxxx/Account/Home/Index
В этом случае в файле Program.cs можно не определять маршрут для области:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); var app = builder.Build(); // добавляем поддержку для контроллеров, которые располагаются вне области app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Также можно использовать префиксы:
[Area("Account")] public class HomeController : Controller { [Route("Profile")] [Route("Profile/{controller}")] [Route("Profile/{controller}/{action}")] public IActionResult Index() { return View(); } }
Для обращения к такому методу Index мы можем использовать следующие адреса: http://localhost:xxxx/Profile, http://localhost:xxxx/Profile/Home и http://localhost:xxxx/Profile/Home/Index
Для упрощения добавления областей в Visual Studio можно использовать специальный шаблон. В частности, нажмем правой кнопкой мыши на папку Areas и в появившемся контекстном меню выберем пункт Add -> Area...
Затем в окне добавления нового элемента выберем пункт MVC Area
Далее будет предложено ввести имя для области
Затем Visual Studio сгенерирует стартовую структуру каталогов области.