Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Несмотря на то, что проект MVC по умолчанию представляет собой четкую структуру разделения на отдельные функциональные части - контроллеры, модели, представления, иногда для более удобной работы над приложением, особенно над большими приложениями, приложение делится на ряд областей (area).
Добавим в проект MVC область. Нажмем правой кнопкой мыши на проект и в появившемся меню выберем Add->Area. В окне добавления области дадим новой области название, например, Store. После этого в структуре проекта произойдет ряд изменений: в проект будет добавлена новая папка Areas, в которую в свою очередь будет добавлена папка Store - непосредственно для нашей новой области. Внутри папки Store фактически окажется мини-проект, в котором будут папки для контроллеров, моделей и представлений и класс регистрации области.
Откроем файл регистрации области StoreAreaRegistration.cs:
using System.Web.Mvc; namespace Routing.Areas.Store { public class StoreAreaRegistration : AreaRegistration { public override string AreaName { get { return "Store"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Store_default", "Store/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } } }
Сгенерированные автоматически здесь определение маршрута показывает, как входящие запросы будут сопоставляться с контроллерами и действиями, определенными в данной области Store. Однако чтобы сопоставление запросов с областью происходило, также надо зарегистрировать все области в файле Global.asax.cs. Правда, вручную не придется это делать, так как при добавлении в проект первой области Visual Studio уже автоматически это делает. Вы можете открыть файл Global.asax.cs и увидеть изменения:
............................ using System.Web.Routing; namespace Routing { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } }
Чтобы протестировать нашу область, мы можем также добавить в папку Controllers, как и в основном проекте, новый контроллер и определить в нем действие. И также определить для действий контроллера представления. Допустим, у нас в области Store определен следующий контроллер AutoController:
public class AutoController : Controller { public string Index() { return "AutoController"; } }
Тогда при запуске приложения мы можем обратиться к методу Index контроллера по адресу /Store/Auto/Index, указав сначала имя области, а потом как обычно имя контроллера и его метода.
Однако что если мы захотим добавить в область контроллер Home с методом Index, как и в основном приложении. Поскольку у нас определен стандартный маршрут, который при запуске приложения будет отсылать нас к методу Index контроллера Home, то система маршрутизации окажется в двойственном положении: она не будет знать, к какому именно контроллеру обращаться - к тому, который определен в основном приложении, или к тому, который определен в области. В итоге вы увидите следующую картину:
Чтобы избежать подобной двойственности, в файле RouteConfig.cs в основном приложении надо непосредственно указать пространство имен контроллера Home, который будет вызываться при запуске приложения:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller="Home", action="Index", id = RouteParameter.Optional }, namespaces: new[] { "Routing.Controllers" } ); } }
В данном случае основное приложение находится в пространстве имен Routing
, а контроллер Home - в пространстве имен Routing.Controllers
.
Если бы мы хотели, чтобы у нас при запуске приложения отрабатывал метод Index, определенный в контроллере Home в области Store, то мы могли
бы указать соответствующее пространство имен, которое в моем случае - Routing.Areas.Store.Controllers
При генерации ссылок в представлениях отдельных областей используются все те хелперы, например, Html.ActionLink
, однако тут есть и некоторые особенности.
Чтобы сгенерировать ссылку на какое-либо действие контроллера, которые находятся внутри области, то мы указываем действие и контроллер (если действие находится в другом контроллере):
@Html.ActionLink("Все книги", "Index", "Book", new { id=10}, null)
В итоге будет сгенерирована ссылка: <a href="Store/Book/Index/10>Все книги</a>
Если же требуемое действие и контроллер находятся в другой области, то мы указываем область в параметре хелпера:
@Html.ActionLink("Все книги", "List", new { area = "Library", controller="Book" })
Сгенерированная ссылка будет выглядеть так: <a href="Library/Book/List/>Все книги</a>
Если же метод и контроллер находятся в основном приложении, то для параметра area определяем пустую строку:
@Html.ActionLink("Все книги", "Index", new { area = "", controller="Home" })