Migração na Web

Movendo seu aplicativo Web do WebMatrix para o ASP.NET MVC 3

Brandon Satrom

Baixar o código de exemplo

Desde janeiro, a Microsoft introduziu um novo modelo de programação para desenvolvimento na Web com o Microsoft .NET Framework chamado Páginas da Web do ASP.NET. Com suporte atualmente por padrão no WebMatrix (web.ms/WebMatrix), as Páginas da Web são um modelo de programação centrado em página que se comporta de forma bastante semelhante ao PHP, em que cada página contém sua própria lógica de negócios, acesso a dados e conteúdo dinâmico para renderizar HTML para o navegador.

Existem várias razões para criar um site no WebMatrix. Mas e se você sabe que desejará mudar para o Visual Studio em algum momento no futuro? Se o ASP.NET MVC 3 for seu estado final, será preciso desenvolver novamente o site no momento da migração? Não é preciso ter medo de ficar preso no WebMatrix e nas Páginas da Web.

As Páginas da Web — como parte da estrutura principal ASP.NET — foram criadas tendo em mente a flexibilidade. E, embora não haja limitações técnicas para Páginas da Web que poderiam forçá-lo a mudar para o ASP.NET MVC, pode ser que, às vezes, isso seja necessário para sua equipe, seu produto ou sua empresa.

Neste artigo, discutiremos algumas das razões pelas quais você poderá optar por migrar (bem como algumas razões para não migrar). Discutiremos também estratégias para mover seu site de Páginas da Web para ASP.NET MVC se optar por isso. Abordaremos como mover de Pages para Views, como tratar a lógica de negócios e o código auxiliar e como introduzir Models em seu aplicativo. Finalmente, discutiremos e mostraremos como preservar URLs de sites existentes por meio do roteamento e com suporte para redirecionamentos permanentes, quando necessário.

Quando migrar?

Antes de mergulhar nas razões para migrar de Páginas da Web para ASP.NET MVC, vamos discutir algumas razões para não fazer isso. Para iniciantes, você não deve mover seu site de Páginas da Web para ASP.NET MVC porque está receoso de que seu aplicativo não esteja dimensionado. Como as Páginas da Web são criadas com base no ASP.NET, elas oferecem muitas das características de desempenho de aplicativos criados para ASP.NET MVC ou Web Forms. Obviamente, cada tipo de aplicativo possui um modelo de execução ligeiramente diferente, mas não há nada diretamente sobre o ASP.NET MVC que o torne inerentemente mais ou menos dimensionável do que um aplicativo de Páginas da Web. Dimensionamento e desempenho têm tanto a ver com decisões de design que você toma ao criar o seu site quanto com a estrutura subjacente escolhida.

Não é uma boa ideia também mover o seu site de Páginas da Web para ASP.NET MVC porque é legal, sexy e você ouviu que alguém está fazendo isso, ou apenas porque deseja trabalhar com seu site no Visual Studio — já é possível fazer isso com os sites de Páginas da Web. ASP.NET MVC é uma opção em arquitetura de aplicativos Web, não uma varinha mágica que torna o seu site instantaneamente melhor. A migração de Páginas da Web para ASP.NET MVC é uma opção, não uma necessidade. E embora a Microsoft tenha feito um excelente trabalho tornando essa migração possível e simples, ela ainda lhe custará tempo, recursos e dinheiro, como qualquer outra migração. Por essas razões, é importante ter certeza de que você migrará para ASP.NET MVC pelas razões corretas.

Uma razão válida pode ser porque o teste da unidade é importante para você e sua equipe. Como o modelo de Páginas da Web é centrado em página, não é possível usar as ferramentas de teste da unidade existentes com sites de Páginas da Web. Testar a interface do usuário da Web — usando ferramentas como WatiN ou Selenium — ainda é possível, mas testar a unidade de nível de código com ferramentas como NUnit ou MsTest não é mais. Se o seu site cresceu em complexidade e o teste da unidade for importante para você, uma migração para ASP.NET MVC fará sentido.

Se você prefere executar um teste de unidade em seu código, pode ser que também prefira alguma medida de separação de problemas em seus aplicativos. E embora seja possível criar um código limpo e separado usando arquivos auxiliares e de código nas Páginas da Web, o modelo não é adaptado para essa separação tão naturalmente como é no ASP.NET MVC. Se a separação de problemas for importante para você e você desejar uma arquitetura de aplicativos que estimule a separação, a migração será uma opção válida.

Além dessas duas, podem surgir outras razões para a migração, dependendo do contexto do seu site ou de sua organização. Se você tiver uma equipe em crescimento e um site que esteja crescendo em complexidade e exija uma funcionalidade de negócios mais rica, seria inteligente migrar. A migração também pode ser necessária para fazer melhor uso de um ecossistema de desenvolvimento mais rico para itens como controle de código-fonte, testes de carga etc.

Preparando para a migração

Neste artigo, vamos usar o modelo de sites Galeria de fotos que é fornecido com o WebMatrix e o migra para ASP.NET MVC. A essência do processo de migração está na movimentação de Pages para Models, Controllers e Views, mas é necessário executar um pouco de trabalho de preparação antes de chegar lá.

Como estamos detalhando as etapas envolvidas em uma migração manual neste breve artigo, não conseguiremos dar a cada etapa uma atenção igual. Nosso objetivo é especificar as etapas principais e mencionar, pelo menos, as considerações secundárias. Optamos também por omitir itens que não estejam relacionados à essência da conversão geral, como práticas recomendadas de acesso a dados, possível estrutura de montagem, injeção de dependência e assim por diante. Esses itens são importantes, mas muitos deles falarão da cultura do desenvolvimento e da preferência pessoal, e podem ser todos especificados em suas refatorações pós-migração.

Também é importante notar que não estamos fazendo uso do recurso Open (Abrir) no Visual Studio no WebMatrix neste artigo, o qual abrirá seu site atual como um projeto do site no Visual Studio. Você pode usar essa opção, mesmo se escolher não migrar para ASP.NET MVC, mas preferimos usar o tipo de projeto do aplicativo Web Visual Studio para ASP.NET MVC, começando com um site vazio e migrar itens manualmente.

Assim, começaremos a migração selecionando Arquivo | Novo | Projeto e selecionando um aplicativo Web ASP.NET MVC 3 com o modelo vazio, usando o Razor como o mecanismo de exibição padrão.

Quando o seu aplicativo de destino estiver configurado, você precisará executar algum trabalho de migração inicial. Aqui está um resumo rápido das etapas iniciais:

  1. Adicione todos os pacotes que estiver usando em seu site de Páginas da Web no site ASP.NET MVC por meio do NuGet (nuget.org).
  2. Adicione referências a System.Web.Helpers, WebMatrix.Data e WebMatrix.WebData. Defina cada uma como Copy Local = true no painel de propriedades.
  3. Mova o conteúdo de _AppStart.cshtml para o método Application_Start de Global.asax. Embora seja possível mover e usar _AppStart como se encontra, recomendamos centralizar sua lógica no Global.asax com o código de inicialização ASP.NET MVC existente.
  4. Adicione <roleManager enabled=true /> à seção <system.web> de sua web.config raiz. O aplicativo Galeria de fotos usa o novo provedor de associação WebSecurity encontrado em WebMatrix.WebData, portanto precisamos dessa entrada em nossa configuração para que o site funcione.
  5. Mova todas as folhas de estilo, arquivos de script e imagens das pastas Content ou Scripts em seu aplicativo. Atualize todos os links de recursos nesses arquivos para seus novos caminhos.
  6. Modifique a Rota padrão em Global.asax para apontar para o controlador Galeria e a ação Padrão.
  7. Copie o Banco de dados do SQL Compact localizado na pasta App_Data para a pasta App_Data do seu site. Se você estiver usando outro banco de dados para seu site, adicione essa cadeia de caracteres de conexão ao arquivo Web.Config em seu aplicativo.

Movendo de Pages para Views

Depois de concluída a configuração inicial do seu site ASP.NET MVC, você estará pronto para migrar a essência do seu site existente: as Pages. Nas Páginas da Web, uma Page (.[cs/vb]html) contém marcação, lógica de negócios e quaisquer acesso a dados necessários para essa página. O componente principal do seu trabalho durante uma migração para ASP.NET MVC será quebrar cada página e dividir seu conteúdo em ações do Controller (lógica de negócios), classes de acesso a dados (acesso a dados) e Views (marcação).

Primeiro, é necessário migrar o Layout do seu site. Semelhante a Páginas mestras no Web Forms e no ASP.NET MVC, as páginas Layout são arquivos que especificam as estruturas de layout do seu site. Páginas da Web e ASP.NET MVC 3 (quando usados com o mecanismo de exibição Razor) usam o mesmo subsistema de Layout, portanto essa parte da migração deverá ser fácil. No site Galeria de fotos, o arquivo root _SiteLayout.cshtml contém nossa estrutura de site. Copie o conteúdo e então navegue para o site ASP.NET MVC. Abra o arquivo Layout localizado em Views/Shared/_Layout.cshtml e cole no conteúdo do _SiteLayout.cshtml.

Depois de concluído, será necessário fazer algumas pequenas alterações no _Layout.cshtml. Primeiro, altere o link de sua folha de estilo para o novo local em seu aplicativo ASP.NET MVC (~/Content/Site.css em vez de ~/Styles/Site.css). Em seguida, será necessário alterar @Page.Title para @ViewBag.Title. Os dois objetos são de tipo dinâmico que podem conter dados de exibição ou outros dados das páginas em seu site, e como você deve ter imaginado, Page é usado para Páginas da Web, enquanto ViewBag é usado para ASP.NET MVC.

A última coisa que você precisa alterar em seu _Layout.cshtml é algo que deverá se lembrar para todas as páginas que migrar para ASP.NET MVC. Observe que _Layout.cshtml usa chamadas @Href para inserir URLs na página. Para qualquer chamada que faça referência a conteúdo estático (scripts, CSS etc.), é possível permanecer inalterada. Você desejará, entretanto, alterar todas as chamadas @Href que apontam para páginas em seu site. Embora elas também funcionem como se encontram após a migração, apontam para URLs estáticas. No ASP.NET MVC, é considerada uma prática recomendada usar o Roteamento do ASP.NET para criar URLs para quando as Views forem renderizadas. O resultado será links mais limpos e menos frágeis vinculados às suas definições de Tabela de rotas, em vez de embutidos no site.

Assim, você desejará alterar todos os links, como a seguir:

<div id="banner">
  <p class="site-title">
    <a href="@Href("~/")">Photo Gallery</a>
  </p>
...
</div>

Em vez disso, você usará @Url.RouteUrl ou @Url.Action:

<div id="banner">
  <p class="site-title">
    <a href="@Url.Action("Default", "Gallery")">Photo Gallery</a>
  </p>
...
</div>

Depois de movido o layout do site, você poderá começar a migrar Pages para Views. Se, em seu aplicativo de Páginas da Web, você tiver algumas páginas .cshtml sendo executadas por chamadas RenderPage, mova-as sob Views/Shared para páginas de todo o site ou para a subpasta Views apropriada para páginas compartilhadas por um controlador, como uma conta. Toda página que chama uma dessas páginas parciais precisará ser atualizada para refletir o novo local.

Todas as páginas restantes devem ser movidas em Views, organizadas em pastas pelo Controller. Como seu site de Páginas da Web não possui o conceito de um Controller, você precisará introduzir os Controllers durante a migração. A boa notícia é que uma forma de estrutura de Controller é evidente no aplicativo Galeria de fotos e ilustra uma prática recomendada a ser seguida em seus próprios sites.

Por exemplo, o modelo de sites Galeria de fotos usa as seguintes pastas para agrupar páginas: Account, Gallery, Photo, Tag e User. Cada pasta contém páginas que ativam alguma funcionalidade relacionada a esse agrupamento. Por exemplo, a pasta Account contém páginas para fazer logon e logoff do site e para registrar usuários. A pasta Galeria contém uma página de listagens da galeria, uma página para adicionar uma nova galeria e uma página para visualizar fotos em uma galeria. As pastas restantes são organizadas de maneira semelhante. Embora essa estrutura não seja obrigatória nos sites de Páginas da Web, ela permite uma migração mais fácil para ASP.NET MVC. Nesse caso, cada pasta é perfeitamente mapeada para um Controller e cada arquivo .cshtml para uma Action e View.

Vamos começar movendo a pasta Account e suas três páginas — Login, Logout e Register — em seu aplicativo ASP.NET MVC no diretório Views. Na linguagem do ASP.NET MVC, suas Pages se tornam instantaneamente Views pela natureza de sua localização no aplicativo. Espere, você ainda não terminou, pois seu aplicativo precisa de um Controller e uma ação para fornecer essas Views ao usuário quando solicitado.

Apresentando Controllers

Pela convenção MVC, o fato de que você possui uma pasta Account em Views significa que você deve ter um Controller chamado AccountController, portanto nossa próxima etapa é criar esse Controller na pasta Controllers. Basta clicar com o botão direito do mouse e selecionar Add | Controller (Adicionar | Controlador). A partir desse Controller vazio, podemos criar métodos de ação que conterão a lógica que agora reside na parte superior das páginas .cshtml movidas para nosso aplicativo.

Especificaremos primeiro Login.cshtml, o qual contém o código na Figura 1.

Figura 1 Lógica de negócios contida em Login.cshtml

Page.Title = "Login";
if (IsPost) {
  var email = Request["email"];
  if (email.IsEmpty()) {
    ModelState.AddError(
      "email", "You must specify an email address.");
  }
  var password = Request["password"];
  if (password.IsEmpty()) {
    ModelState.AddError(
      "password", "You must specify a password.");
  }

  if (ModelState.IsValid) {
    var rememberMe = Request["rememberMe"].AsBool();
    if (WebSecurity.Login(email, password, rememberMe)) { 
      string returnUrl = Request["returnUrl"];        
      if (!returnUrl.IsEmpty()) {
        Context.RedirectLocal(returnUrl);
      } else{
        Response.Redirect("~/");
      }
    } else {
      ModelState.AddFormError(
        "The email or password provided is incorrect.");
    }
  }
}

Observe que há dois cenários sendo manipulados aqui. O primeiro é para quando o usuário carregar a página de logon pela primeira vez. Nesse cenário, a Page define seu título e as transições diretamente para a marcação. O segundo cenário está contido na condicional IsPost e representa a lógica que é executada quando o usuário preenche o formulário de logon e clica no botão Logon.

No ASP.NET MVC, tratamos o processo de entrega de um formulário vazio e a aceitação do envio de um formulário criando dois métodos de ação em nosso Controller, um para o formulário vazio e um para manipular o envio. A primeira ação definirá o título da página e retornará ao modo de exibição de logon, enquanto a segunda conterá a lógica dentro da condicional IsPost. Essas ações estão contidas na Figura 2. Depois de adicionadas essas duas ações, exclua o código do cabeçalho de Login.cshtml.

Figura 2 Ações do controlador de logon

public ActionResult Login() {
  ViewBag.Title = "Login";
  return View();
}

[HttpPost]
public ActionResult Login(string email, string password, 
  bool? rememberMe, string returnUrl) {
  if (email.IsEmpty())
    ModelState.AddModelError("email", 
      "You must specify an email address.");
  if (password.IsEmpty())
    ModelState.AddModelError("password", 
      "You must specify a password.");
  if (!ModelState.IsValid)
    return View();
  if (WebSecurity.Login(email, password, 
    rememberMe.HasValue ? rememberMe.Value : false)) {
    if (!string.IsNullOrEmpty(returnUrl))
      return Redirect(returnUrl);
    return RedirectToAction("Default", "Gallery");
  }

  ModelState.AddModelError("_FORM", 
    "The email or password provided is incorrect");
  return View();
}

Há várias diferenças a serem observadas entre a página original e os métodos de ação resultantes. Para iniciantes, você observará que a condicional IsPost não é necessária. No ASP.NET MVC, criamos uma ação de postagem para a página de logon criando um segundo método de ação de Logon e decorando-o com o atributo [HttpPost]. Agora, nosso primeiro método de Logon não faz nada além de definir a propriedade ViewBag.Title e retornar um ViewResult, que procurará então por uma página de exibição em Views/Account chamada Login.cshtml.

A segunda coisa que você pode observar é que nossa ação de postagem contém vários parâmetros e que todas as chamadas Request que a página original usava não existem mais. Colocando parâmetros em nosso método que corresponde aos nomes de campos em nosso formulário de logon (email, password e rememberMe), podemos usar o fichário de modelo padrão do ASP.NET MVC para que esses itens sejam passados para nós como parâmetros para a ação, o que evita que tenhamos de chamar o objeto Request nós mesmos e tornar nossa lógica de ação mais sucinta.

Finalmente, há algumas pequenas diferenças em como a validação é tratada e os redirecionamentos são executados nas Páginas da Web e nos aplicativos ASP.NET MVC. Em nosso site de Páginas da Web, ModelState.AddError e .AddFormError são as chamadas que usamos para notificar a página de que encontramos dados de formulário inválidos. Em aplicativos ASP.NET MVC, usamos ModelState.AddModelError, que é apenas uma pequena diferença, mas uma alteração necessária em todas as suas páginas. Para redirecionamentos, nosso site de Páginas da Web chama Response.Redirect ao rotear novamente o usuário. No ASP.NET MVC, como nossas ações do Controller devem retornar um ActionResult, chamamos o retorno de RedirectToRoute(“Default”), o que produz o mesmo resultado.

Depois de migrarmos a página de logon, podemos também lidar rapidamente com Logout.cshtml. Nas Páginas da Web, algumas páginas podem conter a lógica e nenhuma marcação se seu propósito for executar uma ação e, em seguida, redirecionar o usuário, como com Logout.cshtml:

@{
  WebSecurity.Logout();
  Response.Redirect("~/");
}

No ASP.NET MVC, adicionaremos uma ação de logout que executa esse trabalho para nós:

public ActionResult Logout() {
  WebSecurity.Logout();
  return RedirectToAction("Default", "Gallery");
}

Como as Views representam apenas os elementos visuais de uma página e nenhuma funcionalidade e criamos uma ação que trata do logout do usuário e de seu redirecionamento, podemos excluir a View Logout.cshtml de nosso aplicativo.

Assim, transformamos nossas páginas Account em exibições copiando-as na pasta Views/Account, criamos um AccountController para tratar das solicitações em nossas páginas Account e implementamos métodos de ação para tratar dos cenários de logon e logout. Nesse ponto, é possível criar e executar o site e anexar Account/Login à barra de endereço do seu navegador (observe que a página inicial padrão aponta para Galeria/Padrão, que ainda não implementamos e, por esse motivo, não será exibido).

A outra parte da funcionalidade do site com a qual você desejará lidar neste ponto é o código e os auxiliares contidos no diretório App_Code de seu site de Páginas da Web. No início da migração, é possível mover esse diretório inteiro sobre seu aplicativo ASP.NET MVC e incluí-lo em seu projeto. Se o diretório contiver qualquer arquivo de código (.cs ou .vb) você poderá mantê-lo em App_Code ou movê-lo para qualquer outro lugar. Seja qual for o caso, precisará alterar a propriedade Build Action de cada arquivo para Compile em vez de Content. Se o diretório contiver arquivos .cshtml com declarações de método @helper, poderá deixá-los e utilizá-los, uma vez que se encontram em seu aplicativo ASP.NET MVC.

Para o restante do site de Páginas da Web, você seguirá um ciclo semelhante de criação de um Controller para cada pasta Views, criando ações para cada Page e movendo o código de cabeçalho de cada página para uma ou mais ações. Sem perda de tempo, você deverá ter todas as páginas corretamente separadas em ações do Controller e em Views. Entretanto, ainda há uma parte do padrão MVC da qual não falamos neste artigo: o Modelo.

Migrando o acesso a dados nas classes de repositório

O seu processo de assumir a lógica de negócios de cada página e mover essa lógica para uma ou mais ações do Controller será bastante direta, com uma exceção: acesso a dados. Embora algumas de suas páginas possam ser semelhantes às páginas de logon e logout e conter alguma lógica e nenhum acesso a dados, a maioria do site Páginas da Web provavelmente usará um banco de dados.

A página Account/Register.cshtml é um exemplo. Quando o usuário concluir o formulário de registro e clicar em Register (Registrar-se), a página fará duas chamadas para o banco de dados, ilustradas na Figura 3.

Figura 3 Lógica do banco de dados Register.cshtml

var db = Database.Open("PhotoGallery");
      
var user = db.QuerySingle("SELECT Email FROM 
UserProfiles WHERE LOWER(Email) = LOWER(@0)", email);
       
if (user == null) {      
  db.Execute(
    "INSERT INTO UserProfiles (Email, DisplayName, Bio) 
    VALUES (@0, @1, @2)", email, email, "");

  try {
    WebSecurity.CreateAccount(email, password);
    WebSecurity.Login(email, password);
    Response.Redirect("~/");
  } catch (System.Web.Security.MembershipCreateUserException e) {
    ModelState.AddFormError(e.ToString());
  }
} else {
  ModelState.AddFormError("Email address is already in use.");
}

Primeiro, a página de registro abre o banco de dados PhotoGallery e retorna um objeto WebMatrix.Data.Database que representa o banco de dados. Em seguida, a página utiliza o objeto para consultar um endereço de e-mail existente com o valor fornecido pelo usuário. Se o endereço não existir, um novo registro UserProfile será criado e uma conta será criada para o usuário usando o provedor de associação WebSecurity.

Desde que tenhamos adicionado uma referência ao WebMatrix.Data e definido a propriedade Copy Local como true, poderemos usar essa lógica de banco de dados sem nenhuma alteração e o site funcionará normalmente. Como você está no meio da migração, essa pode ser a abordagem que você deseja assumir como uma etapa tática para manter o site funcional.

Neste artigo, entretanto, vamos nos aprofundar um pouco mais e criar objetos adicionais que contenham seu acesso a dados, exatamente como faríamos em um aplicativo ASP.NET MVC no qual começamos do zero. Há vários padrões à sua disposição para separar seu Controller e a lógica de acesso a dados. Usaremos o padrão Repository para a Galeria de fotos e pela abstração de nosso acesso a dados nas classes de repositório, podemos encapsular essa lógica e minimizar o impacto de nossa escolha para adicionar objetos Model formais ou um sistema de mapeamento relacional de objeto (ORM), como o Entity Framework, ao longo do processo.

Começaremos criando uma pasta Repositories em nosso aplicativo, junto com uma classe simples chamada AccountRepository.cs. Em seguida, podemos percorrer cada chamada de banco de dados em nossa ação Register e mover essa lógica em nosso repositório, conforme mostrado na Figura 4.

Figura 4 AccountRepository

public class AccountRepository {
  readonly Database _database;
  public AccountRepository() {
    database = Database.Open("PhotoGallery");
  }

  public dynamic GetAccountEmail(string email) { 
    return _database.QuerySingle(
      "SELECT Email FROM UserProfiles 
      WHERE LOWER(Email) = LOWER(@0)", email);
  }
 
  public void CreateAccount(string email) {
    _database.Execute(
      "INSERT INTO UserProfiles 
      (Email, DisplayName, Bio) VALUES (@0, @1, @2)", 
      email, email, "");
  }
}

Adicionamos a chamada ao Database.Open para o construtor de nosso repositório e criamos dois métodos, um para consultar um e-mail da conta e outro para criar a conta.

Observe que o tipo de retorno para GetAccountEmail é dinâmico. No WebMatrix.Data, muitos dos métodos de consulta retornam dynamic ou IEnumerable<dynamic>, e não há razão para não continuar essa prática em seus repositórios enquanto ela for sustentável. 

O novo método Register — usando nosso AccountRespository — é ilustrado na Figura 5.

Figura 5 Ação Register usando AccountRepository

[HttpPost]
public ActionResult Register(string email, string password, 
  string confirmPassword) {

  // Check Parameters (omitted)

  if (!ModelState.IsValid)
    return View();
 
  var db = new AccountRepository();
  var user = db.GetAccountEmail(email);
 
  if (user == null) {
    db.CreateAccount(email);
 
    try {
      WebSecurity.CreateAccount(email, password);
      WebSecurity.Login(email, password);
      return RedirectToAction("Default", "Gallery");
    }
    catch (System.Web.Security.MembershipCreateUserException e) {
      ModelState.AddModelError("_FORM", e.ToString());
    }
  }
  else {
    ModelState.AddModelError("_FORM", 
      "Email address is already in use.");
  }
 
  return View();
}

O uso de tipos de retorno dinâmicos é totalmente aceitável e pode até mesmo ser aconselhável durante uma migração para que você coloque o seu site em funcionamento como um aplicativo ASP.NET MVC completo. Não é necessário usar modelos com rigidez de tipos em um aplicativo ASP.NET MVC, portanto você pode utilizar essa estratégia desde que não precise de uma definição controlada por código de seu modelo de dados. A lógica do Controller e Views de seu aplicativo ASP.NET MVC de modelo dinâmico funcionarão normalmente, com uma exceção.

Talvez você tenha observado que, em seu aplicativo de Páginas da Web, os campos de formulário são definidos explicitamente usando marcação padrão:

<input type="text" />
<input type="submit" />
...

No ASP.NET MVC, a maneira preferencial de usar controles de formulários é usar os métodos auxiliares Html, como Html.TextBox ou Html.TextBoxFor, pois esses métodos usam o Model passado para sua View para definir os valores atuais e manipular a validação do formulário. Se você desejar usar esses métodos auxiliares na pós-migração de suas Views, terá de introduzir objetos Model com rigidez de tipo e não usar tipos dinâmicos em seus repositórios, pois esses métodos auxiliares não podem trabalhar com modelos dinâmicos.

Preservando as URLs do site

As URLs do seu site são importantes. Não importa o estado do seu site, muitas origens externas dependem de suas URLs existentes — mecanismos de pesquisa, documentação, comunicação, scripts de teste e similares. Devido a essas dependências, você não deve alterar arbitrariamente suas URLs, mesmo para uma migração.

Considere o uso do Roteamento do ASP.NET para garantir que as URLs existentes sejam preservadas. O Roteamento do ASP.NET facilita uma solicitação e a corresponde ao recurso correto, em nosso caso, um Controller e uma Action. As Páginas da Web usam um sistema de roteamento diferente do ASP.NET MVC, de modo que será necessário gastar algum tempo para garantir que suas URLs existentes sejam preservadas.

Os aplicativos de Páginas da Web podem manipular URLs com e sem extensões. Por exemplo, essas duas URLs resolvem para a mesma página:

http://mysite/Gallery/Default.cshtml

http://mysite/Gallery/Default

Um aplicativo ASP.NET MVC, entretanto, não tratará a primeira URL usando a extensão .cshtml. Usar as URLs sem extensão em todo o site garantirá que os mecanismos de pesquisa e outros sites dependentes façam o mesmo, o que minimizará o impacto da migração em seu site. Se, no entanto, você precisar tratar as URLs existentes com extensões, poderá criar rotas em seu aplicativo ASP.NET MVC para garantir que elas não sejam quebradas.

Por exemplo, considere a rota padrão de nosso aplicativo Galeria de fotos:

routes.MapRoute(
  "Default", 
  "{controller}/{action}/{id}", 
  new { controller = "Home", 
    action = "Index", id = "" } 
);

Para oferecer suporte a URLs herdadas em nosso sistema, precisaremos incluir rotas adicionais em nossa tabela de rotas acima dessa definição no arquivo Global.asax. Eis um exemplo de uma dessas definições:

routes.MapRoute(
  "LegacyUrl",
  "{controller}/{action}.cshtml/{id}",
  new { controller = "Gallery", 
    action = "Default", id = "" }
);

Nesta entrada de rota, as URLs que contêm a extensão .cshtml são tratadas e enviadas para o Controller e a Action apropriados, supondo que a estrutura existente do seu site Páginas da Web seja mapeado corretamente para uma estrutura Controller/Action.

Ao planejar uma migração, lembre-se de que seu aplicativo pode exigir uma alteração na rota padrão ou mesmo rotas adicionais para oferecer suporte às URLs existentes. Se, no entanto, você decidir quebrar uma URL existente, assegure-se de incluir Actions para tratar redirecionamentos permanentes de usuários.

Conclusão

Para realçar o impacto de uma migração de Páginas da Web para ASP.NET MVC, vamos dar uma olhada na estrutura antes e após de nosso site Galeria de fotos. Na Figura 6, do lado esquerdo, você verá a estrutura do site Páginas da Web no WebMatrix. O lado direito mostra esse site depois de concluída a migração para ASP.NET MVC. Observe que, embora haja diferenças na estrutura, a maioria do resultado final soará familiar para você.

Application Layout Before and After

Figura 6 Layout do aplicativo antes e após

Hoje em dia, os desenvolvedores do ASP.NET possuem três opções de estrutura para escolher: Web Forms, Páginas da Web e ASP.NET MVC. Embora cada uma delas tenha suas vantagens, a escolha de uma não impede você de utilizar outra ou mesmo de migrar para outra em algum momento no futuro. E como as três são criadas com base no ASP.NET, passar de uma para a outra nunca deve estar vinculado a razões técnicas. Se você optar por mover, as semelhanças entre Páginas da Web e ASP.NET MVC permitiria continuar a usar tecnologias como NuGet, Razor, Web Deploy, IIS Express e SQL Compact sem modificação.

Se você criar o seu aplicativo usando Páginas da Web e decidir que uma movimentação é uma boa ideia para você, migrar de Páginas da Web para ASP.NET MVC será o caminho menos complicado, especialmente se tomar algumas decisões iniciais de design em suas Páginas da Web para agrupar páginas em pastas por funcionalidade, usar URLs relativas para todos os recursos e colocar toda a lógica de negócios na parte superior de cada página. Quando chegar o momento da migração, você descobrirá que a movimentação de Páginas da Web para ASP.NET MVC é fácil e direta, como desejado.

Você poderá encontrar links para várias das técnicas e tecnologias usadas neste artigo, e muito mais, em bit.ly/WebMatrixToMVC.

Brandon Satrom trabalha como divulgador e desenvolvedor sênior da Microsoft fora de Austin, Texas. Ele mantém um blog em userInexperience.com, podcasts em DeveloperSmackdown.com e, além disso, você pode acompanhá-lo no Twitter em twitter.com/BrandonSatrom.

Clark Sell trabalha como divulgador e desenvolvedor sênior da Microsoft fora de Chicago. Ele mantém um blog em csell.net, podcasts em DeveloperSmackdown.com e, além disso, você pode acompanhá-lo no Twitter em twitter.com/csell5.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Phil Haack e Erik Porter