Desenvovedores web correndo atrás das novidades A versão 1.0 do ASP.Net MVC foi lançada seis meses atrás. Todo mundo ainda está pegando o jeito do novo framework web da Microsoft, ainda está se acostumando, que eu acho que a maioria não percebeu que eles estão tão ativos no desenvolvimento do framework que já lançaram, dois meses atrás, o primeiro preview da versão 2. As coisas andam rápido, não é?

Essa história toda de versões é um pouco confusa, então vou tentar explicar um pouco para deixar claro em que pé estamos:
A versão 2.0 é a versão que virá instalada por padrão no Visual Studio 2010, segundo dizem alguns funcionários da Microsoft. Não sei se seremos capazes de trabalhar também com a versão 1.1 no Visual Studio 2010, mas imagino que sim. A versão 1.1 é absolutamente idêntica com relação a funcionalidades à versão 1.0, mudando apenas a versão do .Net Framework, que na versão 1.0 utiliza o 3.5SP1, e na versão 1.1 o 4.0 é utilizado. A versão 1.1 foi liberada para trabalhar já com o Visual Studio 2010 Beta 1, e pode ser baixada desde junho, já que o Beta 1 do VS 2010 não possuía nenhuma versão do ASP.Net MVC. O Beta 2 já vai ter uma versão dele, já no preview 2, ou seja, se tudo estiver certo, teremos o preview 2 sendo lançado entre o fim de Outubro e começo de Novembro (lançamento do Beta 2). Update: errei feio, lançado em 30 de Setembro.

Este post é o primeiro de alguns onde vou abordar o primeiro preview da versão 2 do ASP.Net MVC. Neste post vou começar falando de algo muito esperado: áreas! Mas antes disso é bom dizer que a instalação do ASP.Net MVC 2P1 é segura, e pode ser instalada lado a lado da versão 1.0. Ela também não pode ser instalada no VS 2010, só no VS 2008.

Áreas é algo muito útil, que já vinha sendo implementado por alguns componentes open source no mercado, já para a versão 1.0 no ASP.Net MVC. A Microsoft resolveu incluir isso então na v2. Basicamente, áreas suportam nativamente urls mais simpáticas, como /Area1/Controlador1, e /Area2/Controlador1, algo antes só possível de ser feito com algum hack no ASP.Net Routing.

Pra fazer uma estrutura de áreas, neste primeiro preview, você cria pelo menos dois projetos ASP.Net MVC, um é o pai, e o outro é o filho, que vai conter a área. Você pode criar quantas áreas quiser. Aqui, por exemplo, criei o pai (MVC2Application1) e dois filhos (Area1 e Area2):

Estrutura de projeto de áreas

Vejam que os scripts, css, views, controllers, e global.asax não estão nos projetos de área. Fiz também uma referência do projeto principal para os dois filhos.

Incluí então alguns controladores e visões. Deixei tudo muito simples, os controladores e visões são iguaizinhos nos dois projetos de área, mudando só o namespace. Vejam o controlador:

public class Controller1Controller : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    public ActionResult Acao1()
    {
        return View();
    }
    public ActionResult Acao2()
    {
        return View();
    }
}

Essa é uma das views:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Acao1
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Area1 - Acao1</h2>
    <%= Html.ActionLink("Index", "Index")%>
    <%= Html.ActionLink("Acao 2", "Acao2") %>
</asp:Content>

Sem novidades. Código padrão ASP.Net MVC. Vejam que há links entre as views, mas esses links direcionam às mesmas views.

Quero ser capaz de linkar da minha área padrão para outras, daí acrescentei o seguinte à minha view Index do projeto padrão:

<%= Html.ActionLink("Home", "Index", "Home", new { area = "Rota padrão" }, null)%><br />
<%= Html.ActionLink("Área 1", "Index", "Controller1", new { area = "Area1" }, null)%><br />
<%= Html.ActionLink("Área 2", "Index", "Controller1", new { area = "Area2" }, null)%><br />
<%= Html.ActionLink("Área 1 - Acao 1", "Acao1", "Controller1", new { area = "Area1" }, null)%><br />
<%= Html.ActionLink("Área 1 - Acao 2", "Acao1", "Controller1", new { area = "Area1" }, null)%><br />
<%= Html.ActionLink("Área 2 - Acao 1", "Acao1", "Controller1", new { area = "Area2" }, null)%><br />
<%= Html.ActionLink("Área 2 - Acao 2", "Acao2", "Controller1", new { area = "Area2" }, null)%>

Precisamos agora configurar as rotas. Precisamos informar como configurar as áres. O código vai no método RegisterRoutes, no global.asax.cs, no lugar do código anterior, você coloca esse (não precisa excluir o código de IgnoreRoute):

routes.MapAreaRoute(
    "Area2",
    "Rota area 2",
    "MinhaArea2/{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = ""},
    new[] {"Area2.Controllers"}
    );

routes.MapAreaRoute(
    "Area1",
    "Rota area 1",
    "Area1/{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = ""},
    new[] {"Area1.Controllers"}
    );

routes.MapAreaRoute(
    "Main",
    "Rota padrão",
    "{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = ""},
    new[] { "Mvc2Application1.Controllers" }
    );

Dessa forma, as novas rotas ficam configuradas pra trabalhar com áreas. Vejam que para a área 1, usei a url /Area1, mas pra área 2 usei a url /MinhaArea2. O novo código utiliza um método chamado MapAreaRoute, em vez do método MapRoute que existia antes.

É importante que você coloque o mapeamento das áreas filhas antes do mapeamento padrão de rotas. O mapeamento padrão é “{controller}/{action}/{id}”, se você colocar fora de ordem, as rotas filhas nunca vão ser encontradas, já que rotas são avaliadas na ordem em que são registradas. Isso significa que se mapear primeiro a rota padrão, ao chamar /Area2/Controller1/Acao1, em vez de bater com a área correta, vai bater com a rota padrão, e mapear “Area2” como o controller, “Controller1” como ação, e “Acao1” como id.

Agora a cola final. Para tudo isso funcionar, você precisa descarregar o projeto:

Descarregando o projeto

Editá-lo:

Editando o projeto

E onde estava comentado, descomentar:

<!-- To enable MVC area subproject support, uncomment the following two lines:
-->
<UsingTask TaskName="Microsoft.Web.Mvc.Build.CreateAreaManifest" 
    AssemblyName="Microsoft.Web.Mvc.Build, 
    Version=2.0.0.0, Culture=neutral, 
    PublicKeyToken=31bf3856ad364e35" />
<UsingTask TaskName="Microsoft.Web.Mvc.Build.CopyAreaManifests" 
    AssemblyName="Microsoft.Web.Mvc.Build, 
    Version=2.0.0.0, Culture=neutral, 
    PublicKeyToken=31bf3856ad364e35" />

Você também precisa descomentar o seguinte xml. Se for do projeto pai, descomente esse:

<!-- If this is an area parent project, uncomment the following lines:
-->
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Parent" 
AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />

Senão, descomente esse:

<!-- If this is an area child project, uncomment the following line:
-->
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" 
AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />

Depois recarregue o projeto. Se ele perguntar como você deve recarregar o projeto, escolha recarregar normalmente.

Isso é tudo. Rode, e vai funcionar.

Vejam aqui como o método Html.ActionLink funcionou conforme o esperado, criando o link corretamente:

Áreas linkando conforme o esperado

Aqui podemos ver dentro de uma área. O ActionLink agora aponta para a própria área, se eu não informar nenhuma. O código deste ActionLink é:

<%= Html.ActionLink("Acao 2", "Acao2") %>

Áreas sendo exibidas

Tem alguns bugzinhos, mas nada de mais, que impeça o uso. Vou reportar lá no Connect. Experimentem, está ficando bem legal. Se você quiser, também pode baixar o fonte do Preview 2 lá no Codeplex.

Neste momento, o processo de utilização de rotas está muito manual. Temos que descarregar projeto, editar o csproj, etc. Ainda que isso só seja feito uma única vez para cada rota, tenho certeza que até a versão final isso deve passar a ter um suporte melhor do Visual Studio. Outra coisa que o time está olhando é a utilização de áreas com um único projeto, sem precisar criar projetos adicionais para isso.

O que acharam?

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.