Области в ASP.NET Core

Авторы: Дхананджай Кумар (Dhananjay Kumar) и Рик Андерсон (Rick Anderson)

Области — это ASP.NET функция, используемая для упорядочивания связанных функций в группу в виде отдельной:

  • Пространство имен для маршрутизации.
  • Структура папок для представлений и Razor страниц.

Использование областей создает иерархию для маршрутизации путем добавления другого параметра маршрута, areaв controller и action страницу Razor page.

Области позволяют секционировать веб-приложение ASP.NET Core на небольшие функциональные группы, каждая из которых содержит собственный набор Razor Pages, контроллеров, представлений и моделей. По сути, область является структурой внутри приложения. В веб-проекте ASP.NET Core логические компоненты, например страницы, модель, контроллер и представление, хранятся в разных папках. Среда выполнения ASP.NET Core использует соглашения об именовании для создания связи между этими компонентами. Крупное приложение может быть целесообразно разделить на отдельные высокоуровневые области функциональности. Например, в приложении для электронной коммерции можно выделить несколько подразделений: для оформления заказов, выставления счетов или поиска. Каждая из этих единиц имеет собственную область для хранения представлений, контроллеров, Razor страниц и моделей.

Использовать области в проекте рекомендуется в таких случаях:

  • Приложение состоит из нескольких высокоуровневых функциональных частей, которые могут быть разделены логически.
  • Необходимо разделить приложение так, чтобы с каждой функциональной областью можно было работать отдельно.

Если вы используете Razor страницы, см . статью "Области с Razor страницами " в этом документе.

Области для контроллеров с представлениями

Типичное веб-приложение ASP.NET Core, использующее области, контроллеры и представления, содержит следующие элементы.

  • Структура папки области.

  • Контроллеры с атрибутом [Area] для привязки контроллера к области:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • Маршрут области, добавленный в Program.cs:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddControllersWithViews();
    
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapControllerRoute(
        name: "MyArea",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
    
    app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    
    app.Run();
    

Структура папки области

Рассмотрим приложение с двумя логическими группами: товары и услуги. При использовании областей структура папок будет выглядеть следующим образом.

  • Имя проекта
    • Областях
      • Продукция
        • Контроллеры
          • HomeController.cs
          • ManageController.cs
        • Представления
          • Home
            • Index.cshtml
          • Руководить
            • Index.cshtml
            • About.cshtml
      • Услуги
        • Контроллеры
          • HomeController.cs
        • Представления
          • Home
            • Index.cshtml

Хотя предыдущий макет часто используется при работе с областями, только файлы представления необходимы для использования этой структуры папок. Обнаружение подходящего файла представления области происходит в следующем порядке.

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Привязка контроллера к области

Контроллеры области назначаются атрибутом [Area] :

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers;

[Area("Products")]
public class ManageController : Controller
{
    public IActionResult Index()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }

    public IActionResult About()
    {
        ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
        return View();
    }
}

Добавление маршрута области

Маршруты области обычно используют обычную маршрутизацию , а не маршрутизацию атрибутов. При маршрутизации на основе соглашений учитывается порядок. Как правило, маршруты с областями должны находиться раньше в таблице маршрутов, так как они более точные, чем маршруты без областей.

{area:...} можно использовать как токен в шаблонах маршрутов, если пространство URL-адресов одинаково во всех областях:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

В приведенном выше коде exists применяет ограничение, связанное с тем, что маршрут должен соответствовать области. Использование сMapControllerRoute:{area:...}

  • Является наименее сложным механизмом добавления маршрутизации в области.
  • Соответствует всем контроллерам с атрибутом [Area("Area name")] .

В следующем коде используется MapAreaControllerRoute для создания двух именованных маршрутов областей:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapAreaControllerRoute(
    name: "MyAreaProducts",
    areaName: "Products",
    pattern: "Products/{controller=Home}/{action=Index}/{id?}");

app.MapAreaControllerRoute(
    name: "MyAreaServices",
    areaName: "Services",
    pattern: "Services/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Дополнительные сведения см. в разделе Маршрутизация области.

В следующем коде из примера загрузки показано создание ссылок с указанной областью:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Пример скачивания включает частичное представление, содержащее следующее:

  • Предыдущие ссылки.
  • Ссылки, аналогичные предыдущему, кроме area не указаны.

Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области и контроллере.

Если область или контроллер не указаны, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании внешних значений создаются неправильные ссылки с разметкой, которая не указывает область.

Дополнительные сведения см. в разделе Маршрутизация к действиям контроллера.

Общий макет для областей с использованием файла _ViewStart.cshtml

Чтобы предоставить общий макет для всего приложения, сохраните файл _ViewStart.cshtml в корневой папке приложения. Дополнительные сведения см. в разделе "Макет" в ASP.NET Core

Корневая папка приложения

Корневая папка приложения — это папка, Program.cs содержащая файл в веб-приложении, созданном с помощью шаблонов ASP.NET Core.

_ViewImports.cshtml

/Views/_ViewImports.cshtml, для MVC и /Pages/_ViewImports.cshtml for Razor Pages, не импортируется в представления в областях. Используйте один из следующих подходов для предоставления импорта представлений для всех представлений:

  • Добавьте _ViewImports.cshtml в корневую папку приложения. Файл _ViewImports.cshtml в корневой папке приложения будет применяться ко всем представлениям в приложении.
  • Скопируйте файл _ViewImports.cshtml в соответствующую папку представления в областях. Например, приложение Pages, созданное Razor с отдельными учетными записями пользователей, имеет файл _ViewImports.cshtml в следующих папках:
    • /Areas//Pages/Identity_ViewImports.cshtml
    • /Pages/_ViewImports.cshtml

Файл _ViewImports.cshtml обычно содержит вспомогательные функции тегов, импортируемые @usingи @inject операторы. Дополнительные сведения см. в разделе "Импорт общих директив".

Измените папку области по умолчанию, где хранятся представления

Следующий код изменяет папку области по умолчанию с "Areas" на "MyAreas":

using Microsoft.AspNetCore.Mvc.Razor;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<RazorViewEngineOptions>(options =>
{
    options.AreaViewLocationFormats.Clear();
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
    options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
});

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "MyArea",
    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Области со Razor страницами

Области с Razor страницами требуют Areas/<area name>/Pages папку в корневом каталоге приложения. В этом примере приложения используется следующая структура папок:

  • Имя проекта
    • Областях
      • Продукция
        • Страниц
          • _ViewImports
          • О программе
          • Индекс
      • Услуги
        • Страниц
          • Руководить
            • О программе
            • Индекс

В следующем коде из этого примера показано создание ссылок с указанной областью (например, asp-area="Products").

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Пример загрузки включает частичное представление, которое содержит указанные выше ссылки и те же ссылки без указания области. Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области.

Если область не указана, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании значений окружения создаются неверные ссылки. Для примера рассмотрим ссылки, созданные с помощью следующего кода.

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

В приведенном выше коде:

  • Ссылка, созданная с помощью <a asp-page="/Manage/About"> будет правильной, только если последний запрос был к странице в области Services. Например, /Services/Manage/, /Services/Manage/Index или /Services/Manage/About.
  • Ссылка, созданная с помощью <a asp-page="/About"> будет правильной, только если последний запрос был к странице в области /Home.
  • Это код из этого примера.

Импорт пространства имен и вспомогательных функций тегов с помощью файла _ViewImports

Файл _ViewImports.cshtml можно добавить в каждую папку page области для импорта пространства имен и вспомогательных тегов на каждую Razor страницу в папке.

Рассмотрите область служб в примере кода, которая не содержит файл _ViewImports.cshtml. В следующей разметке показана страница /Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<div>
  ViewData["routeInfo"]:  @ViewData["routeInfo"]
</div>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

В этой разметке:

  • Полное имя класса должно использоваться для указания модели (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Вспомогательные функции тегов включены с помощью @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers.

В примере загрузка область продуктов содержит следующий файл _ViewImports.cshtml:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

В следующей разметке показана страница /Products/AboutRazor :

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

В предыдущем файле пространство имен и директива @addTagHelper импортируются в файл с помощью файла Areas/Products/Pages/_ViewImports.cshtml.

Дополнительные сведения см. в разделах Управление областью действия вспомогательной функции тега и Импорт общих директив.

Общий макет для Razor областей страниц

Чтобы совместно использовать общий макет для всего приложения, переместите _ViewStart.cshtml в корневую папку приложения.

Публикация областей

Все файлы CSHTML и файлы в каталоге wwwroot публикуются в выходных данных, если в файл CSPROJ включен <Project Sdk="Microsoft.NET.Sdk.Web">.

Добавление области MVC с помощью Visual Studio

В Обозреватель решений щелкните проект правой кнопкой мыши и выберите добавить > новый шаблонный элемент, а затем выберите область MVC.

Дополнительные ресурсы

Области — это ASP.NET функция, используемая для упорядочивания связанных функций в группу в виде отдельной:

  • Пространство имен для маршрутизации.
  • Структура папок для представлений и Razor страниц.

Использование областей создает иерархию для маршрутизации путем добавления другого параметра маршрута, areaв controller и action страницу Razor page.

Области позволяют секционировать веб-приложение ASP.NET Core на небольшие функциональные группы, каждая из которых содержит собственный набор Razor Pages, контроллеров, представлений и моделей. По сути, область является структурой внутри приложения. В веб-проекте ASP.NET Core логические компоненты, например страницы, модель, контроллер и представление, хранятся в разных папках. Среда выполнения ASP.NET Core использует соглашения об именовании для создания связи между этими компонентами. Крупное приложение может быть целесообразно разделить на отдельные высокоуровневые области функциональности. Например, в приложении для электронной коммерции можно выделить несколько подразделений: для оформления заказов, выставления счетов или поиска. Каждая из этих единиц имеет собственную область для хранения представлений, контроллеров, Razor страниц и моделей.

Использовать области в проекте рекомендуется в таких случаях:

  • Приложение состоит из нескольких высокоуровневых функциональных частей, которые могут быть разделены логически.
  • Необходимо разделить приложение так, чтобы с каждой функциональной областью можно было работать отдельно.

Просмотреть или скачать пример кода (описание скачивания). Пример загрузки содержит простое приложение для тестирования областей.

Если вы используете Razor страницы, см . статью "Области с Razor страницами " в этом документе.

Области для контроллеров с представлениями

Типичное веб-приложение ASP.NET Core, использующее области, контроллеры и представления, содержит следующие элементы.

Структура папки области

Рассмотрим приложение с двумя логическими группами: товары и услуги. При использовании областей структура папок будет выглядеть следующим образом.

  • Имя проекта
    • Областях
      • Продукция
        • Контроллеры
          • HomeController.cs
          • ManageController.cs
        • Представления
          • Home
            • Index.cshtml
          • Руководить
            • Index.cshtml
            • About.cshtml
      • Услуги
        • Контроллеры
          • HomeController.cs
        • Представления
          • Home
            • Index.cshtml

Хотя предыдущий макет часто используется при работе с областями, только файлы представления необходимы для использования этой структуры папок. Обнаружение подходящего файла представления области происходит в следующем порядке.

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Привязка контроллера к области

Контроллеры области назначаются атрибутом [Area] :

using Microsoft.AspNetCore.Mvc;
using Microsoft.Docs.Samples;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }

        public IActionResult About()
        {
            ViewData["routeInfo"] = ControllerContext.MyDisplayRouteInfo();
            return View();
        }
    }
}

Добавление маршрута области

Маршруты области обычно используют обычную маршрутизацию , а не маршрутизацию атрибутов. При маршрутизации на основе соглашений учитывается порядок. Как правило, маршруты с областями должны находиться раньше в таблице маршрутов, так как они более точные, чем маршруты без областей.

{area:...} можно использовать как токен в шаблонах маршрутов, если пространство URL-адресов одинаково во всех областях:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "MyArea",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

В приведенном выше коде exists применяет ограничение, связанное с тем, что маршрут должен соответствовать области. Использование сMapControllerRoute:{area:...}

  • Является наименее сложным механизмом добавления маршрутизации в области.
  • Соответствует всем контроллерам с атрибутом [Area("Area name")] .

В следующем коде используется MapAreaControllerRoute для создания двух именованных маршрутов областей:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapAreaControllerRoute(
            name: "MyAreaProducts",
            areaName: "Products",
            pattern: "Products/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapAreaControllerRoute(
            name: "MyAreaServices",
            areaName: "Services",
            pattern: "Services/{controller=Home}/{action=Index}/{id?}");

        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Дополнительные сведения см. в разделе Маршрутизация области.

В следующем коде из примера загрузки показано создание ссылок с указанной областью:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage",
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Пример скачивания включает частичное представление, содержащее следующее:

  • Предыдущие ссылки.
  • Ссылки, аналогичные предыдущему, кроме area не указаны.

Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области и контроллере.

Если область или контроллер не указаны, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании внешних значений создаются неправильные ссылки с разметкой, которая не указывает область.

Дополнительные сведения см. в разделе Маршрутизация к действиям контроллера.

Общий макет для областей с использованием файла _ViewStart.cshtml

Чтобы предоставить общий макет для всего приложения, сохраните _ViewStart.cshtml его в корневой папке приложения. Дополнительные сведения см. в разделе "Макет" в ASP.NET Core

Корневая папка приложения

Корневая папка приложения — это папка, содержащаяся Startup.cs в веб-приложении, созданном с помощью шаблонов ASP.NET Core.

_ViewImports.cshtml

/Views/_ViewImports.cshtml, для MVC и /Pages/_ViewImports.cshtml для Razor страниц, не импортируется в представления в областях. Используйте один из следующих подходов для предоставления импорта представлений для всех представлений:

  • Добавьте _ViewImports.cshtml в корневую папку приложения. Корневая _ViewImports.cshtml папка приложения будет применяться ко всем представлениям в приложении.
  • Скопируйте файл в _ViewImports.cshtml соответствующую папку представления в областях.

Файл _ViewImports.cshtml обычно содержит вспомогательные функции тегов, импортируемые @usingи @inject операторы. Дополнительные сведения см. в разделе "Импорт общих директив".

Измените папку области по умолчанию, где хранятся представления

Следующий код изменяет папку области по умолчанию с "Areas" на "MyAreas":

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddControllersWithViews();
}

Области со Razor страницами

Области с Razor страницами требуют Areas/<area name>/Pages папку в корневом каталоге приложения. В этом примере приложения используется следующая структура папок:

  • Имя проекта
    • Областях
      • Продукция
        • Страниц
          • _ViewImports
          • О программе
          • Индекс
      • Услуги
        • Страниц
          • Руководить
            • О программе
            • Индекс

В следующем коде из этого примера показано создание ссылок с указанной областью (например, asp-area="Products").

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Пример загрузки включает частичное представление, которое содержит указанные выше ссылки и те же ссылки без указания области. Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области.

Если область не указана, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании значений окружения создаются неверные ссылки. Для примера рассмотрим ссылки, созданные с помощью следующего кода.

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

В приведенном выше коде:

  • Ссылка, созданная с помощью <a asp-page="/Manage/About"> будет правильной, только если последний запрос был к странице в области Services. Например, /Services/Manage/, /Services/Manage/Index или /Services/Manage/About.
  • Ссылка, созданная с помощью <a asp-page="/About"> будет правильной, только если последний запрос был к странице в области /Home.
  • Это код из этого примера.

Импорт пространства имен и вспомогательных функций тегов с помощью файла _ViewImports

Файл _ViewImports.cshtml можно добавить в каждую папку pages области для импорта пространства имен и вспомогательных тегов на каждую Razor страницу в папке.

Рассмотрим область служб примера кода, которая не содержит _ViewImports.cshtml файл. В следующей разметке показана страница /Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

В этой разметке:

  • Полное имя класса должно использоваться для указания модели (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Вспомогательные функции тегов включены с помощью @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers.

В примере скачивания область "Продукты" содержит следующий _ViewImports.cshtml файл:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

В следующей разметке показана страница /Products/AboutRazor :

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

В предыдущем файле пространство имен и @addTagHelper директива импортируются в файл файлом Areas/Products/Pages/_ViewImports.cshtml .

Дополнительные сведения см. в разделах Управление областью действия вспомогательной функции тега и Импорт общих директив.

Общий макет для Razor областей страниц

Чтобы предоставить общий доступ ко всему приложению, переместите _ViewStart.cshtml его в корневую папку приложения.

Публикация областей

Все файлы CSHTML и файлы в каталоге wwwroot публикуются в выходных данных, если в файл CSPROJ включен <Project Sdk="Microsoft.NET.Sdk.Web">.

Добавление области MVC с помощью Visual Studio

В Обозреватель решений щелкните проект правой кнопкой мыши и выберите добавить > новый шаблонный элемент, а затем выберите область MVC.

Области — это возможность ASP.NET, которая служит для объединения связанных функций в группу в виде отдельного пространства имен (для маршрутизации) и структуры папок (для представлений). Использование областей создает иерархию для маршрутизации путем добавления другого параметра маршрута, areaв controller и action страницу Razor page.

Области позволяют секционировать веб-приложение ASP.NET Core на небольшие функциональные группы, каждая из которых содержит собственный набор Razor Pages, контроллеров, представлений и моделей. По сути, область является структурой внутри приложения. В веб-проекте ASP.NET Core логические компоненты, например страницы, модель, контроллер и представление, хранятся в разных папках. Среда выполнения ASP.NET Core использует соглашения об именовании для создания связи между этими компонентами. Крупное приложение может быть целесообразно разделить на отдельные высокоуровневые области функциональности. Например, в приложении для электронной коммерции можно выделить несколько подразделений: для оформления заказов, выставления счетов или поиска. Каждая из этих единиц имеет собственную область для хранения представлений, контроллеров, Razor страниц и моделей.

Использовать области в проекте рекомендуется в таких случаях:

  • Приложение состоит из нескольких высокоуровневых функциональных частей, которые могут быть разделены логически.
  • Необходимо разделить приложение так, чтобы с каждой функциональной областью можно было работать отдельно.

Просмотреть или скачать пример кода (описание скачивания). Пример загрузки содержит простое приложение для тестирования областей.

Если вы используете Razor страницы, см . статью "Области с Razor страницами " в этом документе.

Области для контроллеров с представлениями

Типичное веб-приложение ASP.NET Core, использующее области, контроллеры и представления, содержит следующие элементы.

Структура папки области

Рассмотрим приложение с двумя логическими группами: товары и услуги. При использовании областей структура папок будет выглядеть следующим образом.

  • Имя проекта
    • Областях
      • Продукция
        • Контроллеры
          • HomeController.cs
          • ManageController.cs
        • Представления
          • Home
            • Index.cshtml
          • Руководить
            • Index.cshtml
            • About.cshtml
      • Услуги
        • Контроллеры
          • HomeController.cs
        • Представления
          • Home
            • Index.cshtml

Хотя предыдущий макет часто используется при работе с областями, только файлы представления необходимы для использования этой структуры папок. Обнаружение подходящего файла представления области происходит в следующем порядке.

/Areas/<Area-Name>/Views/<Controller-Name>/<Action-Name>.cshtml
/Areas/<Area-Name>/Views/Shared/<Action-Name>.cshtml
/Views/Shared/<Action-Name>.cshtml
/Pages/Shared/<Action-Name>.cshtml

Привязка контроллера к области

Контроллеры области назначаются атрибутом [Area] :

using Microsoft.AspNetCore.Mvc;

namespace MVCareas.Areas.Products.Controllers
{
    [Area("Products")]
    public class ManageController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            return View();
        }
    }
}

Добавление маршрута области

Маршруты области обычно используют маршрутизацию на основе соглашений, а не атрибутов. При маршрутизации на основе соглашений учитывается порядок. Как правило, маршруты с областями должны находиться раньше в таблице маршрутов, так как они более точные, чем маршруты без областей.

{area:...} можно использовать как токен в шаблонах маршрутов, если пространство URL-адресов одинаково во всех областях:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
          name: "MyArea",
          template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

В приведенном выше коде exists применяет ограничение, связанное с тем, что маршрут должен соответствовать области. Использование {area:...} — это наименее сложный механизм для добавления маршрута к областям.

В следующем коде используется MapAreaRoute для создания двух именованных маршрутов областей:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapAreaRoute(
            name: "MyAreaProducts",
            areaName:"Products",
            template: "Products/{controller=Home}/{action=Index}/{id?}");

        routes.MapAreaRoute(
            name: "MyAreaServices",
            areaName: "Services",
            template: "Services/{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
    });
}

При использовании MapAreaRoute с ASP.NET Core 2.2 см. эту задачу GitHub.

Дополнительные сведения см. в разделе Маршрутизация области.

В следующем коде из примера загрузки показано создание ссылок с указанной областью:

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-controller="Home" asp-action="About">
            Products/Home/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-controller="Home" asp-action="About">
            Services About
        </a>
    </li>
    <li>
        <a asp-area="" asp-controller="Home" asp-action="About">
            /Home/About
        </a>
    </li>
</ul>
<li>Html.ActionLink generated links</li>
<ul>
    <li>
        @Html.ActionLink("Product/Manage/About", "About", "Manage", 
                                                new { area = "Products" })
    </li>
</ul>
<li>Url.Action generated links</li>
<ul>
    <li>
        <a href='@Url.Action("About", "Manage", new { area = "Products" })'>
            Products/Manage/About
        </a>
    </li>
</ul>

Ссылки, создаваемые предыдущим кодом, действуют в любом месте приложения.

Пример загрузки включает частичное представление, которое содержит указанные выше ссылки и те же ссылки без указания области. Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области и контроллере.

Если область или контроллер не указаны, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании значений окружения создаются неверные ссылки.

Дополнительные сведения см. в разделе Маршрутизация к действиям контроллера.

Общий макет для областей с использованием файла _ViewStart.cshtml

Чтобы предоставить общий доступ ко всему приложению, переместите _ViewStart.cshtml его в корневую папку приложения.

_ViewImports.cshtml

В своем стандартном расположении /Views/_ViewImports.cshtml не применяется к областям. Чтобы использовать общие вспомогательные функции тегов или @inject @usingв вашей области, убедитесь, что к представлениям области применяется правильный _ViewImports.cshtml файл. Если требуется одинаковое поведение во всех представлениях, перейдите /Views/_ViewImports.cshtml в корневой каталог приложения.

Измените папку области по умолчанию, где хранятся представления

Следующий код изменяет папку области по умолчанию с "Areas" на "MyAreas":

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.AreaViewLocationFormats.Clear();
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/{1}/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/MyAreas/{2}/Views/Shared/{0}.cshtml");
        options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
    });

    services.AddMvc();
}

Области со Razor страницами

Области с Razor страницами требуют Areas/<area name>/Pages папку в корневом каталоге приложения. В этом примере приложения используется следующая структура папок:

  • Имя проекта
    • Областях
      • Продукция
        • Страниц
          • _ViewImports
          • О программе
          • Индекс
      • Услуги
        • Страниц
          • Руководить
            • О программе
            • Индекс

В следующем коде из этого примера показано создание ссылок с указанной областью (например, asp-area="Products").

<li>Anchor Tag Helper links</li>
<ul>
    <li>
        <a asp-area="Products" asp-page="/About">
            Products/About
        </a>
    </li>
    <li>
        <a asp-area="Services" asp-page="/Manage/About">
            Services/Manage/About
        </a>
    </li>
    <li>
        <a asp-area="" asp-page="/About">
            /About
        </a>
    </li>
</ul>
<li>Url.Page generated links</li>
<ul>
    <li>
        <a href='@Url.Page("/Manage/About", new { area = "Services" })'>
            Services/Manage/About
        </a>
    </li>
    <li>
        <a href='@Url.Page("/About", new { area = "Products" })'>
            Products/About
        </a>
    </li>
</ul>

Ссылки, создаваемые предыдущим кодом, действуют в любом месте приложения.

Пример загрузки включает частичное представление, которое содержит указанные выше ссылки и те же ссылки без указания области. Частичное представление указывается в файле макета, поэтому каждая страница в приложении отображает созданные ссылки. Ссылки, создаваемые без указания области, допустимы только при обращении со страницы в одной области.

Если область не указана, маршрутизация зависит от значений окружения. Текущие значения маршрута текущего запроса считаются значениями окружения для создания ссылки. Во многих случаях для примера приложения при использовании значений окружения создаются неверные ссылки. Для примера рассмотрим ссылки, созданные с помощью следующего кода.

<li>
    <a asp-page="/Manage/About">
        Services/Manage/About
    </a>
</li>
<li>
    <a asp-page="/About">
        /About
    </a>
</li>

В приведенном выше коде:

  • Ссылка, созданная с помощью <a asp-page="/Manage/About"> будет правильной, только если последний запрос был к странице в области Services. Например, /Services/Manage/, /Services/Manage/Index или /Services/Manage/About.
  • Ссылка, созданная с помощью <a asp-page="/About"> будет правильной, только если последний запрос был к странице в области /Home.
  • Это код из этого примера.

Импорт пространства имен и вспомогательных функций тегов с помощью файла _ViewImports

Файл _ViewImports.cshtml можно добавить в каждую папку pages области для импорта пространства имен и вспомогательных тегов на каждую Razor страницу в папке.

Рассмотрим область служб примера кода, которая не содержит _ViewImports.cshtml файл. В следующей разметке показана страница /Services/Manage/AboutRazor Page:

@page
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@model RPareas.Areas.Services.Pages.Manage.AboutModel
@{
    ViewData["Title"] = "Srv Mng About";
}

<h2>/Services/Manage/About</h2>

<a asp-area="Products" asp-page="/Index">
    Products/Index
</a>

В этой разметке:

  • Для указания модели (@model RPareas.Areas.Services.Pages.Manage.AboutModel) необходимо использовать полное доменное имя.
  • Вспомогательные функции тегов включены с помощью @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers.

В примере скачивания область "Продукты" содержит следующий _ViewImports.cshtml файл:

@namespace RPareas.Areas.Products.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

В следующей разметке показана страница /Products/AboutRazor :

@page
@model AboutModel
@{
    ViewData["Title"] = "Prod About";
}

<h2>Products/About</h2>

<a asp-area="Services" asp-page="/Manage/About">
    Services/Manage/About
</a>

В предыдущем файле пространство имен и @addTagHelper директива импортируются в файл файлом Areas/Products/Pages/_ViewImports.cshtml .

Дополнительные сведения см. в разделах Управление областью действия вспомогательной функции тега и Импорт общих директив.

Общий макет для Razor областей страниц

Чтобы предоставить общий доступ ко всему приложению, переместите _ViewStart.cshtml его в корневую папку приложения.

Публикация областей

Все файлы CSHTML и файлы в каталоге wwwroot публикуются в выходных данных, если в файл CSPROJ включен <Project Sdk="Microsoft.NET.Sdk.Web">.