Como Usar Areas no ASP.NET MVC 5?
Renato Haddad
Novembro, 2014
É uma prática normal dividir uma aplicação em áreas lógicas para um melhor entendimento, gerenciamento, manutenção e visão da aplicação. Por exemplo, uma aplicação ERP contém módulos de vendas, contabilidade, estoque, contas a pagar, contas a receber, etc. Sendo assim, o foco deste artigo é explicar como criar áreas ou módulos lógicos dentro de uma aplicação ASP.NET MVC 5. Cabe dizer que o conhecimento deste artigo pode ser aplicado a qualquer versão do MVC.
O pré-requisito para este artigo é qualquer versão do Visual Studio 2013 que tenha templates para projetos ASP.NET MVC.
Projeto de Áreas no ASP.NET MVC 5
Abra o VS 2013, selecione File / New Project (Ctrl + Shift + N). Na janela aberta, selecione a linguagem Visual C#, a categoria Web e nos templates, ASP.NET Web Application. O nome do projeto será ArtigoAreasMVC, conforme a figura 1.
Figura 1 – Novo projeto de Areas
Clique no botão OK, e na janela aberta, selecione o template MVC, conforme figura 2. Deixe apenas este checkbox selecionado, não é preciso incluir outro template.
Figura 2 – Template do projeto MVC
Como iremos criar uma área de administração neste projeto, clique no botão “Change Authentication” e selecione “Individual User Accounts”, conforme a figura 3, pois para ter acesso a área de administração é preciso estar logado. Clique no botão OK e aguarde o VS criar o projeto.
Figura 3 – Tipo de Autenticação
Criar uma Área
Como explicado anteriormente, uma área é uma estrutura lógica do projeto, portanto, no Solution Explorer, clique com o botão direito no nome do projeto e selecione Add / Area. Conforme a figura 4, é aberta uma janela para informar o nome da Área, neste caso, Admin.
Figura 4 – Nova Área
Clique no botão Add e note que é criada uma nova pasta chamada Area contento a pasta Admin, que é o nome da área criada. E, como o projeto é MVC, são criadas as mesmas estruturas dos Controllers, Models e Views para esta nova área Admin, conforme a figura 5. Sendo assim, todo Controller referente à administração deverá ser inserido aqui, assim como todos os Models e Views.
Figura 5 – Estrutura MVC do Admin
Agora, adicione um novo Controller chamado HomeController dentro da pasta Admin/Controllers, conforme a figura 6.
Figura 6 – Novo Controller do Admin
Veja o código do HomeController, o qual contém apenas a Action Index que retorna uma View. Observe o namespace completo, isto influenciará no arquivo de configuração da rota e nas chamadas dos links na página principal do projeto ou qualquer outra página. Falarei sobre isto com mais detalhes logo mais.
using System.Web.Mvc;
namespace ArtigoAreasMVC.Areas.Admin.Controllers
{
public class HomeController : Controller
{
// GET: Admin/Home
public ActionResult Index()
{
return View();
}
}
}
Como esta Action Index retorna uma View, precisamos cria-la. Portanto, clique com o botão direito no nome da Action Index e selecione Add View. O nome da View será Index e o template será vazio, conforme a figura 7.
Figura 7 – Adicionar a View Index
Clique no botão Add, aguarde a criação da mesma. O conteúdo você pode colocar o que desejar, portanto, para efeito do artigo, o conteúdo exibido a seguir é o suficiente para exibir a página no navegador.
@{
ViewBag.Title = "Index";
}
<h2>Home do ADMIN</h2>
Na pasta Views, abra o arquivo _ViewStart.cshtml e note que o caminho completo do Layout é a página _Layout.cshtml que está dentro de Admin/Views.
@{
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
Agora, na pasta Views/Shared, abra o arquivo _Layout.cshtml, o qual é a página master da administração.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - Administração</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - administração do sistema</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
E, como toda pasta de áreas pode ter configurações próprias, é criado automaticamente o arquivo web.config. E a rota para esta nova pasta Admin, como fica? Aqui é um ponto chave para o entendimento sobre navegação. Também é criado o arquivo AdminAreaRegistration.cs nesta pasta, contendo o método RegisterArea. Note como que a rota está definida, sendo: Admin/controller/action/id.
using System.Web.Mvc;
namespace ArtigoAreasMVC.Areas.Admin
{
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
Execute a aplicação e abra a página Index do Admin, conforme a figura 8, informando o caminho completo Admin/Home/Index.
Figura 8 – Página do Admin
Claro que desta forma a página será encontrada, no entanto, se colocar apenas /Admin, será exibido o erro, conforme a figura 9, pois a rota não está correta.
Figura 9 – Erro na rota
Pare a execução, abra o arquivo AdminAreaRegistration.cs e inclua o nome do controller = “Home” na lista de parâmetros default. Em seguida, execute a página novamente abrindo-a como https://localhost:35349/admin e veja que tudo funcionará. O 35349 é dinâmico, depende da sua máquina ok.
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
//new { action = "Index", id = UrlParameter.Optional } // original
// adiciona-se o nome do controller
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Agora, o próximo passo é inserir a opção Admin no menu principal da aplicação. Para isto, abra a página _Layout.cshtml em ArtigoAreasMVC/Views/Shared, localize as opções de menu e adicione o Admin, conforme o código a seguir. Note que o link ADMIN aponta para a Action Index do Controller Home. E neste caso, é importante você não esquecer de informar que este link pertence a uma área chamada Admin, veja o parâmetro “new { area = "Admin" }”.
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("ADMIN", "Index", "Home", new { area = "Admin" }, null)</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
Mesmo com quase tudo configurado, você pode tentar executar a aplicação, e conforme a figura 10, notará que ocorre um erro, pois a mensagem informa que há múltiplos tipos chamados “Home”.
Figura 10 – Conflito de nomes
Qual a solução? É simples, abra o arquivo RouteConfig.cs na pasta ArtigoAreasMVC\App_Start e inclua o nome do namespace para o ArtigoAreasMVC.Controllers.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
// caso use Areas defina o namespace
, namespaces: new[] { "ArtigoAreasMVC.Controllers" }
);
}
}
Salve e execute novamente a aplicação no navegador. Conforme a figura 11, note que o link ADMIN vai para a página de administração, e o Application name (que é a Home do projeto), retorna para a página principal.
Figura 11 – Navegação para o Admin
Para efeito de artigo, inclui uma nova área chamada Vendas com exatamente a mesma estrutura do Admin, e no menu principal os links ficaram assim:
<li>@Html.ActionLink("ADMIN", "Index", "Home", new { area = "Admin" }, null)</li>
<li>@Html.ActionLink("VENDAS", "Index", "Home", new { area = "Vendas" }, null)</li>
Acesso somente Autorizados
Para efeito simplista de autorização de acesso ao Controller Admin, inseri o atributo [Authorize] acima do nome do HomeController. Isto fará com que somente usuário logados podem acessar este Controller, independente da quantidade de Actions. Sei que isto é tópico para outro artigo, mas é tão simples de se implementar que resolvi fazer neste artigo. Vale dizer que se tiver tiver um Controller com 5 Actions e quiser que apenas algumas sejam executadas logadas, coloque o [Authorize] nos atributos destas Actions.
[Authorize]
public class HomeController : Controller
{
// GET: Admin/Home
public ActionResult Index()
{
return View();
}
}
Execute a aplicação e tente ir para o Admin. Note que não conseguirá acesso, terá que se registrar primeiro, conforme a figura 12.
Figura 12 – Registro de Login
Abra a página _Layout.cshtml em Areas/Admin/Views/Shared e adicione as linhas da DIV que mostra o nome do usuário logado, logo abaixo do menu “Application name”.
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
<div class="text-info">
@User.Identity.Name
</div>
Salve a alteração e vá para a página do Admin. Conforme a figura 13, veja que o nome do usuário logado aparece. O layout fica pela sua criatividade.
Figura 13 – Página do Admin logado
Conclusão
Agora que você já sabe como estruturar a sua aplicação em módulos lógicos para um melhor entendimento e manutenção dos códigos, aplique o conhecimento adquirido neste artigo. E, desta forma já aproveitamos toda a estrutura, convenções e padrões de aplicação MVC sem ter que ficar recriando o que já existe. Sei que muitos times tem um estilo próprio de estruturar um projeto, isto está correto também, o importante é que você entenda e aplique uma estrutura lógica. Você realmente sentirá uma diferença quando o projeto for médio ou grande.
Agradeço a oportunidade de poder compartilhar o conhecimento deste artigo. Qualquer dúvida e preparação de times de desenvolvimento, por favor me contate.
Sobre o Autor
Renato Haddad (rehaddad@msn.com – www.renatohaddad.com ) é MVP, MCPD e MCTS, palestrante em eventos da Microsoft em diversos países, ministra treinamentos focados em produtividade com o VS.NET 2013/2015, ASP.NET 4/5, Entity Framework, Reporting Services, Windows Phone e Windows 8. Visite o blog https://weblogs.asp.net/renatohaddad.