.NET

9 dez, 2014

Como usar áreas no ASP.NET MVC 5

Publicidade

É 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.
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, pois não é preciso incluir outro template.

Figura 2 – Template do projeto MVC.
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.
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.
Figura 4 – Nova Área.

Clique no botão Add e note que é criada uma nova pasta chamada área, contendo 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.
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.
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.

C#

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 criá-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.
Figura 7 – Adicionar a View Index.

Clique no botão Add e 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.

C#

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

C#

@{
    Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}

Agora, na pasta Views/Shared, abra o arquivo _Layout.cshtml, que é 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.

C#

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.
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.
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, abrindo-a novamente como http://localhost:35349/admin e veja que tudo funcionará. O 35349 é dinâmico, depende da sua máquina ok.

C#

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” }”.

C#

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

C#

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

C#

<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 o usuário logados possa 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 um Controller com 5 Actions e quiser que apenas algumas sejam executadas logadas, coloque o [Authorize] nos atributos destas Actions.

C#

[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 e terá que se registrar primeiro, conforme a figura 12.

Figura 12 – Registro de Login.
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”.

C#

@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.
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 têm um estilo próprio de estruturar um projeto e 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.