Области (Areas)

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Несмотря на то, что проект 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" })
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850