Partilhar via


Áreas em ASP.NET Core

Por Dhananjay Kumar e Rick Anderson

As áreas são um recurso ASP.NET usado para organizar a funcionalidade relacionada em um grupo como um separado:

  • Namespace para encaminhamento.
  • Estrutura de Pastas para Visualizações e Páginas.

O uso de áreas cria uma hierarquia com a finalidade de roteamento, adicionando outro parâmetro de rota, area, para controller e action ou uma Razor Página page.

As áreas fornecem uma maneira de particionar um aplicativo Web ASP.NET Core em grupos funcionais menores, cada um com seu próprio conjunto de Razor páginas, controladores, exibições e modelos. Uma área é efetivamente uma estrutura dentro de um aplicativo. Em um projeto Web ASP.NET Core, componentes lógicos como Pages, Model, Controller e View são mantidos em pastas diferentes. O tempo de execução do ASP.NET Core usa convenções de nomenclatura para criar a relação entre esses componentes. Para um aplicativo grande, pode ser vantajoso particioná-lo em áreas separadas de alto nível de funcionalidade. Por exemplo, um aplicativo de comércio eletrônico com várias unidades de negócios, como checkout, faturamento e pesquisa. Cada uma dessas unidades tem sua própria área para conter visualizações, controladores, Razor páginas e modelos.

Considere o uso de Áreas em um projeto quando:

  • O aplicativo é feito de vários componentes funcionais de alto nível que podem ser separados logicamente.
  • Você deseja particionar o aplicativo para que cada área funcional possa ser trabalhada de forma independente.

Se estiver a utilizar Razor Pages, consulte Áreas com Razor Páginas neste documento.

Áreas para controladores com vistas

Um aplicativo Web ASP.NET Core típico que usa áreas, controladores e modos de exibição contém o seguinte:

  • Uma estrutura de pastas de área.

  • Controladores com o [Area] atributo de associar o controlador à área:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • A rota da área adicionada a 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();
    

Estrutura de pastas de área

Considere um aplicativo que tenha dois grupos lógicos, Produtos e Serviços. Usando áreas, a estrutura de pastas seria semelhante à seguinte:

  • Nome do projeto
    • Areas
      • Products
        • Controllers
          • HomeController.cs
          • ManageController.cs
        • Views
          • Home
            • Index.cshtml
          • Manage
            • Index.cshtml
            • About.cshtml
      • Services
        • Controllers
          • HomeController.cs
        • Views
          • Home
            • Index.cshtml

Embora o layout anterior seja típico ao usar Áreas, somente os arquivos de exibição são necessários para usar essa estrutura de pastas. Exibir pesquisas de descoberta para um arquivo de exibição de área correspondente na seguinte ordem:

/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

Associar o controlador a uma Área

Os controladores de área são designados com o [Area] atributo:

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();
    }
}

Adicionar rota de área

As rotas de área normalmente usam roteamento convencional em vez de roteamento de atributos. O roteamento convencional é dependente da ordem. Em geral, as rotas com áreas devem ser colocadas mais cedo na tabela de rotas, pois são mais específicas do que as rotas sem área.

{area:...} Pode ser usado como um token em modelos de rota se o espaço de URL for uniforme em todas as áreas:

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();

No código anterior, exists aplica uma restrição de que a rota deve corresponder a uma área. Usando {area:...} com MapControllerRoute:

  • É o mecanismo menos complicado para adicionar roteamento a áreas.
  • Corresponde a todos os controladores com o [Area("Area name")] atributo.

O código a seguir usa MapAreaControllerRoute para criar duas rotas de área nomeadas:

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();

Para obter mais informações, consulte Roteamento de área.

O código a seguir do download de exemplo mostra a geração de links com a área especificada:

<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>

O download de exemplo inclui uma exibição parcial que contém:

  • Os links anteriores.
  • Links semelhantes ao anterior, exceto que area não é especificado.

A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área e controlador.

Quando a área ou o controlador não é especificado, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos com a marcação que não especifica a área.

Para obter mais informações, consulte Roteamento para ações do controlador.

Layout compartilhado para áreas usando o arquivo _ViewStart.cshtml

Para compartilhar um layout comum para todo o aplicativo, mantenha o _ViewStart.cshtml na pasta raiz do aplicativo. Para obter mais informações, consulte Layout no ASP.NET Core

Pasta raiz do aplicativo

A pasta raiz do aplicativo é a pasta que contém o Program.cs arquivo em um aplicativo Web criado com os modelos ASP.NET Core.

_ViewImports.cshtml

/Views/_ViewImports.cshtml, para MVC, e /Pages/_ViewImports.cshtml para Razor Pages, não é importado para visualizações em áreas. Use uma das seguintes abordagens para fornecer importações de 'views' para todas as 'views':

  • Adicione _ViewImports.cshtml à pasta raiz do aplicativo. Um _ViewImports.cshtml na pasta raiz da aplicação será aplicado a todas as vistas na aplicação.
  • Copie o ficheiro _ViewImports.cshtml para a pasta de vistas apropriada sob as áreas. Por exemplo, um Razor aplicativo Páginas criado com contas individuais tem um arquivo _ViewImports.cshtml nas seguintes pastas:
    • /áreas/Identity/páginas/_ViewImports.cshtml
    • /Pages/_ViewImports.cshtml

O arquivo _ViewImports.cshtml normalmente contém importações de Tag Helpers@usinge @inject instruções. Para obter mais informações, consulte Importando diretivas compartilhadas.

Alterar a pasta da área padrão onde as exibições são armazenadas

O código a seguir altera a pasta de área padrão de "Areas" para "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();

Áreas com Razor páginas

As áreas com Razor Páginas requerem uma Areas/<area name>/Pages pasta na raiz da aplicação. A seguinte estrutura de pastas é usada com o aplicativo de exemplo:

  • Nome do projeto
    • Areas
      • Products
        • Pages
          • _ViewImports
          • About
          • Index
      • Services
        • Pages
          • Manage
            • About
            • Index

O código a seguir do download de exemplo mostra a geração de links com a área especificada (por exemplo, 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>

O download de exemplo inclui uma exibição parcial que contém os links anteriores e os mesmos links sem especificar a área. A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área.

Quando a área não é especificada, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos. Por exemplo, considere os links gerados a partir do seguinte código:

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

Para o código anterior:

  • O link gerado a partir de <a asp-page="/Manage/About"> está correto apenas quando a última solicitação foi para uma página na área de Services. Por exemplo, /Services/Manage/, /Services/Manage/Index, ou /Services/Manage/About.
  • O link gerado a partir de <a asp-page="/About"> está correto somente quando a última solicitação foi para uma página em /Home.
  • O código é do download de exemplo.

Importar o namespace e os Tag Helpers com o arquivo _ViewImports

Um arquivo _ViewImports.cshtml pode ser adicionado a cada área da pasta Pages para importar o namespace e os Tag Helpers para cada Razor Página na pasta.

Considere a área Serviços do código de exemplo, que não contém um arquivo _ViewImports.cshtml . A marcação a seguir mostra a página /Services/Manage/AboutRazor :

@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>

Na marcação anterior:

  • O nome da classe totalmente qualificada deve ser usado para especificar o modelo (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Os Ajudantes de Tags são ativados por @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

No download de exemplo, a área Produtos contém o seguinte arquivo _ViewImports.cshtml :

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

A marcação a seguir mostra a página /Products/AboutRazor :

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

No arquivo anterior, o namespace e a diretiva @addTagHelper são importados pelo ficheiro Areas/Products/Pages/_ViewImports.cshtml.

Para obter mais informações, consulte Gerenciando o escopo do auxiliar de tag e Importando diretivas compartilhadas.

Layout compartilhado para Razor áreas de páginas

Para compartilhar um layout comum para todo o aplicativo, mova o _ViewStart.cshtml para a pasta raiz do aplicativo.

Áreas de Publicação

Todos os arquivos *.cshtml e arquivos dentro do diretório wwwroot são publicados na saída quando <Project Sdk="Microsoft.NET.Sdk.Web"> são incluídos no arquivo *.csproj.

Adicionar área MVC com o Visual Studio

No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione ADICIONAR > Novo Item de Andaime e, em seguida, selecione Área MVC.

Recursos adicionais

As áreas são um recurso ASP.NET usado para organizar a funcionalidade relacionada em um grupo como um separado:

  • Namespace para encaminhamento.
  • Estrutura de Pastas para Visualizações e Páginas.

O uso de áreas cria uma hierarquia com a finalidade de roteamento, adicionando outro parâmetro de rota, area, para controller e action ou uma Razor Página page.

As áreas fornecem uma maneira de particionar um aplicativo Web ASP.NET Core em grupos funcionais menores, cada um com seu próprio conjunto de Razor páginas, controladores, exibições e modelos. Uma área é efetivamente uma estrutura dentro de um aplicativo. Em um projeto Web ASP.NET Core, componentes lógicos como Pages, Model, Controller e View são mantidos em pastas diferentes. O tempo de execução do ASP.NET Core usa convenções de nomenclatura para criar a relação entre esses componentes. Para um aplicativo grande, pode ser vantajoso particioná-lo em áreas separadas de alto nível de funcionalidade. Por exemplo, um aplicativo de comércio eletrônico com várias unidades de negócios, como checkout, faturamento e pesquisa. Cada uma dessas unidades tem sua própria área para conter visualizações, controladores, Razor páginas e modelos.

Considere o uso de Áreas em um projeto quando:

  • O aplicativo é feito de vários componentes funcionais de alto nível que podem ser separados logicamente.
  • Você deseja particionar o aplicativo para que cada área funcional possa ser trabalhada de forma independente.

Visualize ou baixe o código de exemplo (como fazer o download). O exemplo de download fornece um aplicativo básico para áreas de teste.

Se estiver a utilizar Razor Pages, consulte Áreas com Razor Páginas neste documento.

Áreas para controladores com vistas

Um aplicativo Web ASP.NET Core típico que usa áreas, controladores e modos de exibição contém o seguinte:

  • Uma estrutura de pastas de área.

  • Controladores com o [Area] atributo de associar o controlador à área:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • A rota da área adicionada à inicialização:

    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?}");
    });
    

Estrutura de pastas de área

Considere um aplicativo que tenha dois grupos lógicos, Produtos e Serviços. Usando áreas, a estrutura de pastas seria semelhante à seguinte:

  • Nome do projeto
    • Areas
      • Products
        • Controllers
          • HomeController.cs
          • ManageController.cs
        • Views
          • Home
            • Index.cshtml
          • Manage
            • Index.cshtml
            • About.cshtml
      • Services
        • Controllers
          • HomeController.cs
        • Views
          • Home
            • Index.cshtml

Embora o layout anterior seja típico ao usar Áreas, somente os arquivos de exibição são necessários para usar essa estrutura de pastas. Exibir pesquisas de descoberta para um arquivo de exibição de área correspondente na seguinte ordem:

/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

Associar o controlador a uma Área

Os controladores de área são designados com o atributo [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();
        }
    }
}

Adicionar rota de área

As rotas de área normalmente usam roteamento convencional em vez de roteamento de atributos. O roteamento convencional é dependente da ordem. Em geral, as rotas com áreas devem ser colocadas mais cedo na tabela de rotas, pois são mais específicas do que as rotas sem área.

{area:...} Pode ser usado como um token em modelos de rota se o espaço de URL for uniforme em todas as áreas:

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?}");
    });
}

No código anterior, exists aplica uma restrição de que a rota deve corresponder a uma área. Usando {area:...} com MapControllerRoute:

  • É o mecanismo menos complicado para adicionar roteamento a áreas.
  • Corresponde a todos os controladores com o [Area("Area name")] atributo.

O código a seguir usa MapAreaControllerRoute para criar duas rotas de área nomeadas:

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?}");
    });
}

Para obter mais informações, consulte Roteamento de área.

O código a seguir do download de exemplo mostra a geração de links com a área especificada:

<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>

O download de exemplo inclui uma exibição parcial que contém:

  • Os links anteriores.
  • Links semelhantes ao anterior, exceto que area não é especificado.

A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área e controlador.

Quando a área ou o controlador não é especificado, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos com a marcação que não especifica a área.

Para obter mais informações, consulte Roteamento para ações do controlador.

Layout compartilhado para áreas usando o arquivo _ViewStart.cshtml

Para compartilhar um layout comum para todo o aplicativo, mantenha o _ViewStart.cshtml na pasta raiz do aplicativo. Para obter mais informações, consulte Layout no ASP.NET Core

Pasta raiz do aplicativo

A pasta raiz do aplicativo é a pasta que contém Startup.cs no aplicativo Web criado com os modelos ASP.NET Core.

_ViewImports.cshtml

/Views/_ViewImports.cshtml, para MVC e /Pages/_ViewImports.cshtml para Razor Páginas, não é importado para visualizações em áreas. Use uma das seguintes abordagens para fornecer importações de 'views' para todas as 'views':

  • Adicione _ViewImports.cshtml à pasta raiz do aplicativo. A _ViewImports.cshtml na pasta raiz do aplicativo será aplicada a todas as visualizações no aplicativo.
  • Copie o arquivo _ViewImports.cshtml para a pasta de vista apropriada nas áreas.

O _ViewImports.cshtml arquivo geralmente contém importações de Auxiliares de Tag, @using e instruções @inject. Para obter mais informações, consulte Importando diretivas compartilhadas.

Alterar a pasta da área padrão onde as exibições são armazenadas

O código a seguir altera a pasta de área padrão de "Areas" para "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();
}

Áreas com Razor páginas

As áreas com Razor Páginas requerem uma Areas/<area name>/Pages pasta na raiz da aplicação. A seguinte estrutura de pastas é usada com o aplicativo de exemplo:

  • Nome do projeto
    • Areas
      • Products
        • Pages
          • _ViewImports
          • About
          • Index
      • Services
        • Pages
          • Manage
            • About
            • Index

O código a seguir do download de exemplo mostra a geração de links com a área especificada (por exemplo, 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>

O download de exemplo inclui uma exibição parcial que contém os links anteriores e os mesmos links sem especificar a área. A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área.

Quando a área não é especificada, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos. Por exemplo, considere os links gerados a partir do seguinte código:

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

Para o código anterior:

  • O link gerado a partir de <a asp-page="/Manage/About"> está correto apenas quando a última solicitação foi para uma página na área de Services. Por exemplo, /Services/Manage/, /Services/Manage/Index, ou /Services/Manage/About.
  • O link gerado a partir de <a asp-page="/About"> está correto somente quando a última solicitação foi para uma página em /Home.
  • O código é do download de exemplo.

Importar o namespace e os Tag Helpers com o arquivo _ViewImports

Um _ViewImports.cshtml ficheiro pode ser adicionado à pasta Pages de cada área para importar o namespace e os Auxiliares de Tag para cada Razor Página na pasta.

Considere a área Serviços do código de exemplo, que não contém um _ViewImports.cshtml arquivo. A marcação a seguir mostra a página /Services/Manage/AboutRazor :

@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>

Na marcação anterior:

  • O nome da classe totalmente qualificada deve ser usado para especificar o modelo (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Os Ajudantes de Tags são ativados por @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

No download de exemplo, a área Produtos contém o seguinte _ViewImports.cshtml arquivo:

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

A marcação a seguir mostra a página /Products/AboutRazor :

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

No arquivo anterior, o namespace e a diretiva @addTagHelper são importados pelo arquivo Areas/Products/Pages/_ViewImports.cshtml.

Para obter mais informações, consulte Gerenciando o escopo do auxiliar de tag e Importando diretivas compartilhadas.

Layout compartilhado para Razor áreas de páginas

Para compartilhar um layout comum para todo o aplicativo, mova o _ViewStart.cshtml para a pasta raiz do aplicativo.

Áreas de Publicação

Todos os arquivos *.cshtml e arquivos dentro do diretório wwwroot são publicados na saída quando <Project Sdk="Microsoft.NET.Sdk.Web"> são incluídos no arquivo *.csproj.

Adicionar área MVC com o Visual Studio

No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione ADICIONAR > Novo Item de Andaime e, em seguida, selecione Área MVC.

As áreas são um recurso ASP.NET usado para organizar a funcionalidade relacionada em um grupo como um namespace separado (para roteamento) e estrutura de pastas (para exibições). O uso de áreas cria uma hierarquia com a finalidade de roteamento, adicionando outro parâmetro de rota, area, para controller e action ou uma Razor Página page.

As áreas fornecem uma maneira de particionar um aplicativo Web ASP.NET Core em grupos funcionais menores, cada um com seu próprio conjunto de Razor páginas, controladores, exibições e modelos. Uma área é efetivamente uma estrutura dentro de um aplicativo. Em um projeto Web ASP.NET Core, componentes lógicos como Pages, Model, Controller e View são mantidos em pastas diferentes. O tempo de execução do ASP.NET Core usa convenções de nomenclatura para criar a relação entre esses componentes. Para um aplicativo grande, pode ser vantajoso particioná-lo em áreas separadas de alto nível de funcionalidade. Por exemplo, um aplicativo de comércio eletrônico com várias unidades de negócios, como checkout, faturamento e pesquisa. Cada uma dessas unidades tem sua própria área para conter visualizações, controladores, Razor páginas e modelos.

Considere o uso de Áreas em um projeto quando:

  • O aplicativo é feito de vários componentes funcionais de alto nível que podem ser separados logicamente.
  • Você deseja particionar o aplicativo para que cada área funcional possa ser trabalhada de forma independente.

Visualize ou baixe o código de exemplo (como fazer o download). O exemplo de download fornece um aplicativo básico para áreas de teste.

Se estiver a utilizar Razor Pages, consulte Áreas com Razor Páginas neste documento.

Áreas para controladores com vistas

Um aplicativo Web ASP.NET Core típico que usa áreas, controladores e modos de exibição contém o seguinte:

  • Uma estrutura de pastas de área.

  • Controladores com o [Area] atributo de associar o controlador à área:

    [Area("Products")]
    public class ManageController : Controller
    {
    
  • A rota da área adicionada à inicialização:

    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?}");
    });
    

Estrutura de pastas de área

Considere um aplicativo que tenha dois grupos lógicos, Produtos e Serviços. Usando áreas, a estrutura de pastas seria semelhante à seguinte:

  • Nome do projeto
    • Areas
      • Products
        • Controllers
          • HomeController.cs
          • ManageController.cs
        • Views
          • Home
            • Index.cshtml
          • Manage
            • Index.cshtml
            • About.cshtml
      • Services
        • Controllers
          • HomeController.cs
        • Views
          • Home
            • Index.cshtml

Embora o layout anterior seja típico ao usar Áreas, somente os arquivos de exibição são necessários para usar essa estrutura de pastas. Exibir pesquisas de descoberta para um arquivo de exibição de área correspondente na seguinte ordem:

/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

Associar o controlador a uma Área

Os controladores de área são designados com o atributo [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();
        }
    }
}

Adicionar rota de área

As rotas de área normalmente usam roteamento convencional em vez de roteamento de atributos. O roteamento convencional é dependente da ordem. Em geral, as rotas com áreas devem ser colocadas mais cedo na tabela de rotas, pois são mais específicas do que as rotas sem área.

{area:...} Pode ser usado como um token em modelos de rota se o espaço de URL for uniforme em todas as áreas:

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?}");
    });
}

No código anterior, exists aplica uma restrição de que a rota deve corresponder a uma área. Usar {area:...} é o mecanismo menos complicado para adicionar roteamento a áreas.

O código a seguir usa MapAreaRoute para criar duas rotas de área nomeadas:

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?}");
    });
}

Ao usar MapAreaRoute com o ASP.NET Core 2.2, consulte este problema do GitHub.

Para obter mais informações, consulte Roteamento de área.

O código a seguir do download de exemplo mostra a geração de links com a área especificada:

<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>

Os links gerados com o código anterior são válidos em qualquer lugar do aplicativo.

O download de exemplo inclui uma exibição parcial que contém os links anteriores e os mesmos links sem especificar a área. A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área e controlador.

Quando a área ou o controlador não é especificado, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos.

Para obter mais informações, consulte Roteamento para ações do controlador.

Layout compartilhado para áreas usando o arquivo _ViewStart.cshtml

Para compartilhar um layout comum para todo o aplicativo, mova o _ViewStart.cshtml para a pasta raiz do aplicativo.

_ViewImports.cshtml

Em sua localização padrão, /Views/_ViewImports.cshtml não se aplica a áreas. Para usar auxiliares de tag comuns, @usingou @inject em sua área, certifique-se de que um arquivo adequado _ViewImports.cshtmlse aplique às suas visualizações de área. Se quiser o mesmo comportamento em todas as suas vistas, mova /Views/_ViewImports.cshtml para a raiz da aplicação.

Alterar a pasta da área padrão onde as exibições são armazenadas

O código a seguir altera a pasta de área padrão de "Areas" para "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();
}

Áreas com Razor páginas

As áreas com Razor Páginas requerem uma Areas/<area name>/Pages pasta na raiz da aplicação. A seguinte estrutura de pastas é usada com o aplicativo de exemplo:

  • Nome do projeto
    • Areas
      • Products
        • Pages
          • _ViewImports
          • About
          • Index
      • Services
        • Pages
          • Manage
            • About
            • Index

O código a seguir do download de exemplo mostra a geração de links com a área especificada (por exemplo, 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>

Os links gerados com o código anterior são válidos em qualquer lugar do aplicativo.

O download de exemplo inclui uma exibição parcial que contém os links anteriores e os mesmos links sem especificar a área. A exibição parcial é referenciada no arquivo de layout, portanto, cada página no aplicativo exibe os links gerados. Os links gerados sem especificar a área só são válidos quando referenciados a partir de uma página na mesma área.

Quando a área não é especificada, o roteamento depende dos valores ambientais . Os valores de rota atuais da solicitação atual são considerados valores ambientais para geração de link. Em muitos casos para o aplicativo de exemplo, usar os valores de ambiente gera links incorretos. Por exemplo, considere os links gerados a partir do seguinte código:

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

Para o código anterior:

  • O link gerado a partir de <a asp-page="/Manage/About"> está correto apenas quando a última solicitação foi para uma página na área de Services. Por exemplo, /Services/Manage/, /Services/Manage/Index, ou /Services/Manage/About.
  • O link gerado a partir de <a asp-page="/About"> está correto somente quando a última solicitação foi para uma página em /Home.
  • O código é do download de exemplo.

Importar o namespace e os Tag Helpers com o arquivo _ViewImports

Um _ViewImports.cshtml ficheiro pode ser adicionado à pasta Pages de cada área para importar o namespace e os Auxiliares de Tag para cada Razor Página na pasta.

Considere a área Serviços do código de exemplo, que não contém um _ViewImports.cshtml arquivo. A marcação a seguir mostra a página /Services/Manage/AboutRazor :

@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>

Na marcação anterior:

  • O nome de domínio totalmente qualificado deve ser usado para especificar o modelo (@model RPareas.Areas.Services.Pages.Manage.AboutModel).
  • Os Ajudantes de Tags são ativados por @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

No download de exemplo, a área Produtos contém o seguinte _ViewImports.cshtml arquivo:

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

A marcação a seguir mostra a página /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>

No arquivo anterior, o namespace e a diretiva @addTagHelper são importados pelo arquivo Areas/Products/Pages/_ViewImports.cshtml.

Para obter mais informações, consulte Gerenciando o escopo do auxiliar de tag e Importando diretivas compartilhadas.

Layout compartilhado para Razor áreas de páginas

Para compartilhar um layout comum para todo o aplicativo, mova o _ViewStart.cshtml para a pasta raiz do aplicativo.

Áreas de Publicação

Todos os arquivos *.cshtml e arquivos dentro do diretório wwwroot são publicados na saída quando <Project Sdk="Microsoft.NET.Sdk.Web"> são incluídos no arquivo *.csproj.