Migração de aplicativos

Migre seus aplicativos do ASP.NET 1.1 para o Visual Studio 2010

Jonathan Waldman

Se você trabalha com o ASP.NET há alguns anos, é provável que já tenha criado soluções usando o Visual Studio 2003 para o Microsoft .NET Framework 1.1. Nos últimos anos, foram lançadas as versões .NET Framework 2.0, 3.0 e 3.5, que são mais recentes e apresentam grande variedade de recursos, e talvez você tenha se perguntado se valeria a pena ou se seria viável atualizar os seus confiáveis aplicativos .NET Framework 1.1 para uma delas.

Hoje, à medida que o novo .NET Framework 4 vai sendo adotado por desenvolvedores do mundo inteiro, talvez você se sinta mais interessado do que nunca em considerar seriamente um esforço de migração. Se decidir por isso, tenha a certeza de que a Microsoft fornece ferramentas úteis que facilitam uma empreitada desse porte, o que resulta em aplicativos ASP.NET modernizados que podem se beneficiar com as vantagens das últimas inovações do .NET Framework. Especificamente, mostrarei como revigorar soluções ASP.NET 1.1 através da migração para o Visual Studio 2010 (Professional, Premium ou Ultimate); desse modo, elas poderão ser direcionadas para as versões 2.0, 3.0, 3.5 ou 4 do .NET Framework.

Por que migrar?

Ainda que o seu objetivo seja simplesmente manter os sites atuais do ASP.NET 1.1, as opções de suporte e extensibilidade estão diminuindo. Como desenvolvedor 1.1, você deve estar preocupado porque a Microsoft desativou o suporte base para o Visual Studio 2003 em 14 de outubro de 2008 — e declarou que não lançará mais service packs para o Visual Studio 2003 ou o .NET Framework 1.1. (No entanto, a Microsoft oferecerá suporte estendido para o Visual Studio 2003 até 8 de outubro de 2013.)

Todavia, devemos preveni-lo de que é cada vez maior o número de fornecedores que têm deixado de oferecer ou de dar suporte a componentes que podem ser executados no .NET Framework 1.1 ou que estendem o IDE do Visual Studio 2003. Na verdade, seus aplicativos Web .NET Framework 1.1 e o IDE do Visual Studio 2003 estão sendo alienados e caindo no esquecimento.

 Mas ainda existem outros motivos. São tantos os aprimoramentos feitos nas linguagens de programação .NET Framework, C# e Visual Basic .NET e no IDE do Visual Studio que migrar os seus sites do .NET 1.1 para o .NET 2.0 ou outra versão mais recente (que chamarei de 2.0+) finalmente ajudaria você a aperfeiçoá-los com as mais novas ferramentas e tecnologias, além de todos os modernos recursos de estrutura e linguagem (como páginas mestras, AJAX, Windows Communication Foundation [WCF], Silverlight, LINQ, classes parciais, genéricos, expressões lambda e métodos anônimos) já adotados pelos principais desenvolvedores .NET. De modo geral, quanto mais alta for a versão da estrutura escolhida para a qual o seu aplicativo ASP.NET será direcionado, maiores serão o potencial e a força que você terá ao seu alcance. Você encontrará suporte sólido não apenas da própria Microsoft (até a publicação deste artigo, a Microsoft oferecia suporte de base para todas as versões da estrutura 2.0+), mas também em fóruns de desenvolvedores ativos e de fornecedores de ferramentas de terceiros. Além disso, existe uma infinidade de livros que abordam todos os aspectos das mais recentes tecnologias — e muitos sites que oferecem cursos em vídeo, blogs, white papers e outras opções de treinamento.

 O mais recente e avançado IDE do Visual Studio 2010 por si só é praticamente uma justificativa para a migração. Ele está gerações à frente do IDE do Visual Studio 2003, dá suporte a novos recursos, como o IntelliTrace, e pode ser estendido com vários e avançados plug-ins de terceiros que asseguram novos níveis de produtividade em programação. Embora sejam raros os usuários que ainda precisarão continuar a usar as versões mais antigas do Visual Studio por inúmeros motivos, o Visual Studio 2010 torna praticamente desnecessária a execução de instalações lado a lado do Visual Studio 2005 e do Visual Studio 2008, pois o Visual Studio 2010 pode ser direcionado para as estruturas 2.0+. No entanto, da mesma forma que o Visual Studio
2005 e o Visual Studio 2008, o Visual Studio 2010 não pode ser direcionado para a estrutura 1.1. Isso significa que ou você precisa continuar executando o Visual Studio 2003 ou deve migrar seu projeto ASP.NET 1.1 para uma estrutura mais nova.

Para finalizar, os desenvolvedores que possuem experiência somente com a estrutura 1.1 simplesmente não são tão bem cotados quanto os que têm experiência com a estrutura 2.0+. A concorrência por cargos de desenvolvedor é alta, por isso você precisa se dar todas as vantagens possíveis; utilizar recursos de estruturas mais novas no código aumentará sua candidatura e credibilidade como desenvolvedor de software profissional.

Problemas de migração

Mas então por que nem todo mundo migrou do ASP.NET 1.1 durante qualquer uma das versões principais do Visual Studio e do .NET Framework desde o Visual Studio 2003? Um dos motivos é que os desenvolvedores teriam de implementar a opção de migração do ASP.NET 1.1 para o ASP.NET 2.0 oferecida pelo Visual Studio 2005. Isso não soa tão mal, mas observe que, quando o Visual Studio 2005 foi distribuído pela primeira vez, ele exigia que um projeto ASP.NET 1.1 fosse convertido para um tipo de projeto Web moderno. Isso significava que a arquitetura propriamente dita em que foi criado um site do ASP.NET 1.1 precisava ser arduamente remodelada e submetida a rigorosos testes de regressão. Muitos desenvolvedores consideraram esse processo o mesmo que recriar o site do zero, o que representa um desafio instransponível em termos técnicos e de custo. Consequentemente, os tomadores de decisões muitas vezes deixaram os sites criados no ASP.NET 1.1 da maneira como estavam.

Para avaliar melhor esse desafio de migração do ASP.NET 1.1 para o ASP.NET 2.0, é importante entender que todos os projetos Web do ASP.NET 1.1 são organizados utilizando-se uma configuração de arquivos e pastas controlada por projeto. Esse tipo de projeto foi originalmente chamado de o “modelo de projeto Web 2003” e hoje é conhecido como WAP (Projeto de Aplicativo Web). Quando o Visual Studio 2005 foi lançado, a Microsoft introduziu um novo tipo de projeto controlado por pastas desenvolvido para o .NET Framework 2.0. Esse tipo de projeto foi originalmente chamado de o “modelo de projeto Web 2005” e hoje é conhecido como WSP (Projeto de Site). (Confuso? Use o truque simples de memorizar os acrônimos em ordem alfabética: WAP vem antes de WSP, assim como o Visual Studio 2003 vem antes do Visual Studio 2005.)

Embora uma discussão detalhada sobre WAPs e WSPs esteja fora do escopo deste artigo, é suficiente dizer que a Microsoft originalmente pretendia que todos os aplicativos Web 1.1 migrados se tornassem WSPs através do Assistente de Conversão incluído. Os desenvolvedores interessados protestaram imediatamente, pois o tipo de projeto WAP original oferecia vantagens técnicas e de desempenho específicas que não existem no tipo de projeto WSP mais novo. Isso rapidamente gerou um furor na comunidade de desenvolvimento em ASP.NET, quando desenvolvedores, gerentes e partes interessadas souberam que a Microsoft havia fornecido apenas uma opção de migração do WAP ASP.NET 1.1 para o WSP ASP.NET 2.0 — e que ela se mostrou cara e demorada, principalmente para sites de alguma complexidade. Para detalhar os problemas técnicos que surgem durante uma migração como essa seria preciso escrever outro artigo, de várias partes; você pode obter mais informações lendo o artigo da biblioteca do MSDN intitulado “Problemas e soluções comuns de conversão de projeto Web” (msdn.microsoft.com/library/aa479312).

Felizmente, a Microsoft respondeu rapidamente e logo ofereceu um Assistente de Conversão revisado no Visual Studio 2005 SP1. Desta vez, o Assistente de Conversão converteria um WAP ASP.NET 1.1 em um WAP ASP.NET 2.0. Mesmo assim, muitos desenvolvedores não souberam dessa opção de migração e, por isso, nunca a exploraram. No Visual Studio 2010, o Assistente de Conversão converte um WAP ASP.NET 1.1 em um WAP ASP.NET 2.0+ (2.0+ refere-se ao fato de que, após a conversão, é possível direcionar para 2.0, 3.0, 3.5 ou 4), o que ainda oferece uma oportunidade de migrar aplicativos Web mais antigos. (Não é possível converter um aplicativo ASP.NET 1.1 em um aplicativo WSP — e provavelmente você não gostaria de fazer isso — usando o Assistente de Conversão do Visual Studio 2010; seria preciso ter acesso ao Assistente de Conversão fornecido no Visual Studio 2005 original lançado antes do SP1.)

Talvez você se interesse em saber que sempre que inicia um novo projeto no Visual Studio 2010, pode escolher se deseja criar um WAP ou um WSP. A Microsoft prometeu oferecer suporte a WAP e WSP nas versões atuais e em todas as versões futuras do .NET Framework.

O processo

A migração de aplicativos ASP.NET 1.1 usando o Visual Studio 2010 consiste nas seguintes etapas abrangentes, que discutiremos em detalhes:

  • Executar o Assistente de Conversão.
  • Definir a estrutura de destino e a página de inicialização.
  • Compilar e corrigir.
  • Converter páginas e controles de usuário em classes parciais.
  • Compilar e corrigir.

Executar o Assistente de Conversão Para usar o Assistente de Conversão para uma conversão de WAP 1.1 para WAP 2.0+ (nosso objetivo), instale a opção Visual Web Developer durante a instalação do Visual Studio 2010. Se não tiver feito isso, terá de adicioná-lo executando a Instalação do Visual Studio 2010 novamente e usando a opção Alterar ou Remover Microsoft Visual Studio 2010; em seguida, escolha Adicionar ou Remover Recursos, depois verifique se o recurso Visual Web Developer está selecionado (veja a Figura 1).

image: Ensure the Visual Web Developer Component Is Installed Before Launching the Conversion Wizard

Figura 1 Verifique se o componente Visual Web Developer está instalado antes de iniciar o Assistente de Conversão

Se o Visual Web Developer não estiver instalado, ainda assim o Assistente de Conversão será inicializado e executado. Ele poderá converter todos os projetos da sua solução, menos o projeto Web. Ele aconselhará você a instalar o Visual Web Developer para converter o projeto Web.

Antes de empreender um esforço de conversão, é recomendável verificar se o aplicativo não somente compila e executa, mas também se é o mais claro e organizado possível. Portanto:

  1. Limpe seu aplicativo Web removendo todos os arquivos não utilizados e desnecessários, limitando-o aos componentes essenciais.
  2. Verifique se cada projeto da solução compila sem erros de tempo de compilação.
  3. Embora eu recomende adicionar a solução ao controle de código-fonte caso ela ainda não esteja configurada para isso, verifique se não foi feito check-out de arquivos exclusivamente do repositório. Com a solução sob o controle de código-fonte, você poderá examinar alterações específicas feitas pelo assistente após a conclusão do processo de conversão.
  4. Verifique se nenhum arquivo ou pasta fora do controle de código-fonte está marcado como somente leitura. Isso permite que o assistente atualize esses arquivos/pastas conforme necessário.
  5. Crie um backup. Se você for executar a solução em uma máquina virtual, é recomendável fazer backup da máquina virtual inteira (ou criar um instantâneo dela). Caso contrário, faça backup do aplicativo inteiro, inclusive de todas as dependências. Se você não tiver certeza quanto às dependências, um bom lugar para consultar é o arquivo da solução do aplicativo (.sln) e os arquivos do projeto específico (.proj), que são arquivos de texto que podem ser inspecionados visualmente. Muitas soluções ASP.NET contêm projetos que apontam para locais de rede ou para pastas fora do diretório base ou das pastas de aplicativo. Não fazer backup dessas dependências pode causar uma enorme dor de cabeça caso você queira restaurar o aplicativo usando os arquivos de backup. Lembre-se de que o processo de migração completo faz alterações em cada projeto do aplicativo, por isso é vantajoso conhecer as dependências do aplicativo antes de começar. Além disso, se você está usando aplicativos que são compartilhados entre vários aplicativos ASP.NET 1.1, observe que, uma vez migradas, essas soluções não podem mais ser abertas no Visual Studio 2003. Caso você trabalhe em um ambiente de equipe, fazer alterações em projetos compartilhados também afeta as soluções de membros da equipe, o que pode resultar em referências a projetos convertidos. Portanto, seja a solução compartilhada entre projetos ou equipes, você deve desassociar projetos compartilhados fazendo cópias deles e assegurando que exista uma cópia local na estação de trabalho de desenvolvimento. O arquivo da solução será alterado se você mover um projeto (para desassociá-lo, por exemplo), por isso convém considerar fazer backup do arquivo da solução antes de alterar qualquer um dos projetos a que ela faz referência — e, depois, fazer um novo backup quando as dependências do projeto tiverem sido devidamente desassociadas, mas antes de executar o Assistente de Conversão. Por fim, talvez você descubra erros nos arquivos da solução original após o término do processo de conversão; ter à mão um backup da solução pré-convertida ajudará você a corrigir esses erros antes de executar o Assistente de Conversão novamente.
  6. Considere configurar um ambiente paralelo: O Visual Studio 2003 e o Visual Studio 2010 podem ser executados lado a lado no mesmo computador, por isso é possível executar o site em ASP.NET 1.1 junto com o site em ASP.NET 2.0+. Isso facilitará o trabalho de controle de qualidade e execução de testes após a migração.

Para iniciar o assistente, abra o arquivo da solução do Visual Studio 2003 usando a opção de menu Arquivo, Abrir, Projeto/Solução do Visual Studio 2010. De imediato você verá a caixa de diálogo introdutória do Assistente de Conversão do Visual Studio (veja a Figura 2). Clique em Avançar.

image: The Visual Studio Conversion Wizard Introductory Dialog

Figura 2 A caixa de diálogo introdutória do Assistente de Conversão do Visual Studio

O Assistente de Conversão pode identificar problemas enquanto processa, e talvez você queira restaurar a solução a partir de um backup, fazer algumas alterações e iniciar o processo novamente do zero. Esta etapa agiliza a criação de um backup (veja a Figura 3), embora coloque todas as dependências da solução na pasta de backup especificada, o que significa que, para fazer a devida restauração, você precisa ter absoluta certeza de que conhece a disposição original dessas pastas que foram submetidas a backup.

image: The Conversion Wizard Gives You an Opportunity to Create a Backup Before Proceeding

Figura 3 O Assistente de Conversão dá a oportunidade de criar um backup antes de prosseguir

Considerando isso, para fazer backup da solução nesta etapa, basta informar um caminho de pasta e o assistente criará uma pasta filha chamada Backup, na qual colocará os arquivos da solução. Cada projeto da solução será submetido a backup em uma subpasta correspondente sob a pasta Backup, mesmo que a origem seja fora da raiz da solução original; portanto, para que o backup seja bem-sucedido, é importante assegurar que os nomes de projeto utilizados sejam exclusivos na solução inteira. Clique em Avançar.

Agora você verá uma última caixa de diálogo, que contém uma recomendação sobre o controle de código-fonte e permissões de leitura/gravação (veja a Figura 4).

image: The Conversion Wizard Advises You Before Letting You Continue

Figura 4 O Assistente de Conversão faz uma recomendação antes de permitir que você continue

Se você optar por fazer um backup, verá o tipo de backup solicitado e o local em que os arquivos de backup serão gravados. Será exibido um resumo do nome da solução que está sendo convertida, junto com todos os seus projetos. Se todas as informações forem precisas e aceitáveis, clique em Concluir.

Agora, talvez você precise informar as credenciais de logon no repositório do controle de código-fonte (como Visual SourceSafe) para poder fazer check-out do projeto.

Agora você verá uma barra de progresso, à medida que cada projeto da solução é convertido. O processo pode levar vários minutos, pois o assistente faz iterações entre os projetos da solução.

O Assistente de Conversão exibe uma mensagem explicando que você concluiu a primeira etapa e que agora é necessário converter o aplicativo Web (veja a Figura 5).

image: The Conversion Wizard Lets You Know that You Will Need to Convert Your Web Project in Order to Complete the Migration

Figura 5 O Assistente de Conversão informa que você precisará converter o projeto Web para concluir a migração

Em seguida, ele avisa que concluiu o processo inicial (veja a Figura 6).

image: The Conversion Wizard Alerts You When the Conversion Is Complete

Figura 6 O Assistente de Conversão avisa quando a conversão é concluída

Desse movo, você pode analisar o log de conversão utilizando o modelo Relatório de Conversão. Esse arquivo, chamado Upgrade­Log.XML, é colocado na mesma pasta que o arquivo .sln da solução. O log de atualização mostra quais arquivos do projeto foram convertidos e exibe todos os erros e mensagens de aviso relevantes. Ele também traz comentários úteis, além de comentários sobre a versão da estrutura para a qual cada projeto é direcionado. Inclui um trecho desse relatório na Figura 7.

image: The Conversion Log Shows Details About the Converted Web Application

Figura 7 O log de conversão mostra detalhes do aplicativo Web convertido

Todos os avisos e erros devem ser examinados. Os avisos (como alterações no caminho relativo de um caminho de backup) geralmente têm a ver com questões técnicas secundárias que normalmente não exigem uma ação da sua parte para que você possa compilar a solução convertida com êxito. No entanto, as mensagens de erro (como referências a um arquivo ausente) devem ser examinadas atentamente e requerem ação, porque de modo geral envolvem problemas que dificultam a compilação bem-sucedida da solução convertida. Se há muitos erros, o log de conversão faz um bom trabalho articulando o tipo de ação necessária, e você também pode encontrar bastante informações adicionais nos arquivos de Ajuda do Visual Studio 2010 ou em vários sites técnicos. Em alguns casos, talvez você ache melhor tomar nota dos erros do log de conversão e corrigi-los nos arquivos de projeto originais do Visual Studio 2003 e não na solução convertida (é nesse momento que o backup feito vem a calhar). Sempre é possível reexecutar o Assistente de Conversão na solução modificada do Visual Studio 2003.

Depois de examinar todos os avisos e corrigir todos os erros, você poderá ignorar as telas finais do Assistente de Conversão. Agora o Assistente de Conversão concluiu suas tarefas. O arquivo da solução (.sln) e os arquivos de projeto (.proj) correspondentes agora estão no formato do Visual Studio 2010. No entanto, você ainda tem algum trabalho pela frente para concluir a migração.

Definir a estrutura de destino e a página de inicialização Quando o Assistente de Conversão for concluído, ele terá configurado o projeto Web do Visual Studio 2003 para executar no .NET Framework 4 e os outros projetos da solução para executar no .NET Framework 2.0. Embora seja aceitável combinar versões de estrutura, recomendo usar um único destino de estrutura para todos os projetos da solução, a menos que existam restrições impostas pela empresa de hospedagem na Web ou pela infraestrutura da organização. (O Visual Studio 2010 modifica o conjunto de recursos do IDE conforme a estrutura de destino em vigor para o projeto ativo. Se o seu projeto estiver direcionado para outras versões de estrutura, talvez você ache o comportamento do IDE enigmático quando alternar entre projetos. Ter todos os projetos com a mesma versão de estrutura permite que o IDE apresente uma interface consistente para todos os projetos e que você programe em uma estrutura consistente.)

Para alterar a estrutura de destino de qualquer um dos seus projetos convertidos, basta clicar com o botão direito do mouse na raiz do projeto, no Gerenciador de Soluções, e selecionar Propriedades. Na página de configuração exibida (veja a Figura 8), selecione a guia Aplicativo e altere a Estrutura de Destino com qualquer um dos valores da estrutura 2.0+.

image: Change the Target Framework for Any Project to 2.0, 3.0, 3.5 or 4

Figura 8 Altere a estrutura de destino de qualquer projeto para 2.0, 3.0, 3.5 ou 4

Para finalizar, defina a página inicial do projeto Web. Para isso, localize a página no Gerenciador de Soluções, clique nela com o botão direito do mouse e selecione a opção Definir como Página Inicial.

Compilar e corrigir Agora que os arquivos da solução e de projeto foram atualizados para o formato do Visual Studio 2010, o WAP ASP.NET 2.0+ está pronto para ser compilado. Para impor a compilação de todos os projetos da solução, recomendo compilar no Visual Studio 2010 usando a opção de menu Compilar, Recompilar Solução. Depois de recompilar, você poderá ver todos os problemas de compilação na janela Lista de Erros (para isso, selecione o menu Exibir e a opção Lista de Erros). Essa janela exibe erros, avisos e mensagens (você pode especificar o que deseja ver na janela ativando os botões Erros, Avisos e Mensagens). Normalmente o Visual Studio 2010 traz uma orientação clara sobre como resolver os itens exibidos na janela Lista de Erros. Caso você não entenda o texto do erro/aviso/mensagem, selecione a linha da janela Lista de Erros que contém a recomendação e pressione a tecla <F1>. Será exibida uma janela de ajuda com informações mais detalhadas sobre o problema (se você não instalou a ajuda local, pode se conectar à Internet para exibi-la). Ainda assim, a maior parte dos erros que você verá serão referentes a alterações na estrutura que geram conflitos de nomes com o código. Isso pode ser corrigido se você qualificar totalmente suas referências com um namespace. Além disso, a maioria dos avisos será relativa a membros obsoletos. Apesar de ainda ser possível usar membros obsoletos, é importante que você saiba que provavelmente eles não terão suporte na próxima versão superior do .NET Framework. Caso veja membros obsoletos e estiver direcionando para a estrutura 2.0, é provável que você não consiga usar esse membro quando decidir direcionar para uma estrutura 3.x ou para a 4.

Você deve reservar algum tempo para corrigir os problemas exibidos na janela Lista de Erros. Você deverá resolver todos os erros e a maioria dos avisos, se não todos, antes de ir para as próximas etapas.

Converter páginas e controles de usuário em classes parciais A próxima etapa envolve a execução de um comando Converter em Aplicativo Web (que chamarei de CWA). Embora seja possível executar esse comando em uma página ou controle de usuário específico para ver o
tipo de alteração que ele faz, é mais rápido executá-lo na solução inteira. Para isso, no Gerenciador de Soluções, clique com o botão direito do mouse no nó Solução e escolha Converter em Aplicativo Web. Esse processo faz o seguinte:

  1. Implementa classes parciais adicionando um novo documento “designer” para páginas e controles de usuário.
  2. Define AutoEventWireup para páginas e controle de usuário.
  3. Adiciona manipuladores de eventos declarativos para cada controle em páginas e controles de usuário.

Os aplicativos ASP.NET 1.1 possuem módulos code-behind (aspx.cs e ascx.cs para C# e aspx.vb e ascx.vb para Visual Basic .NET) que contêm código gerado tanto de autoria do desenvolvedor quanto pelo Web Form Designer. Quando você cria páginas ou controles de usuário no Visual Studio 2003 e adiciona controles a eles usando o Web Form Designer, o IDE adiciona campos de instância protegidos aos módulos code-behind para que você possa fazer referências a esses controles adicionados. Após a execução do comando CWA, é exibido um documento de designer referente a cada página e controle de usuário (o Gerenciador de Soluções mostra esse arquivo somente quando a opção Mostrar Todos os Arquivos está habilitada). Você observará que os nomes de arquivos de designer são iguais à página ou ao controle de usuário, junto com uma extensão designer.cs (C#) ou designer.vb (Visual Basic .NET).

Por exemplo, se você tem uma página chamada MyPage.aspx em C#, haverá um novo documento chamado MyPage.aspx.designer.cs. Esse documento de designer contém campos de instância protegidos que ficavam no módulo code-behind. Esses campos mudaram para o módulo do designer e, portanto, não são mais combinados com o seu código. Isso é possível porque os módulos do designer são classes parciais, o que significa que o comando CWA também transforma o código code-behind da página ou do controle de usuário correspondente em uma classe parcial.

Por exemplo, os campos de instância em C# e Visual Basic .NET são exibidos da seguinte forma nos documentos code-behind de projetos do Visual Studio 2003:

[VB]
Protected WithEvents MyButton As System.Web.UI.WebControls.Button

[C#]
protected System.Web.UI.WebControls.Button MyButton;
The CWA command moves each to a corresponding designer file:
[VB]
Protected WithEvents MyButton As Global.System.Web.UI.WebControls.Button

[C#]
protected global::System.Web.UI.WebControls.Button MyButton;

(global:: indica que a pesquisa de namespace por System deve começar no nível de namespace global e, portanto, assegura que o namespace System da estrutura não será oculto pelo seu namespace System.)

A criação do arquivo de designer é dinâmica, e ele pode ser gerado novamente a qualquer momento. Por isso, é possível excluir o documento designer.cs ou designer.vb com segurança e gerá-lo novamente (ou restaurá-lo se estiver faltando); para isso, basta clicar com o botão direito do mouse no nó da página ou do controle de usuário no Gerenciador de Soluções e reexecutar o comando CWA nele. O comando CWA procura controles de servidor na marcação HTML de uma página ou de um controle de usuário e gera as variáveis de instância necessárias no arquivo de classe parcial do designer. Em seguida, ele remove quaisquer variáveis de instância que ainda aparecem no seu arquivo code-behind (aspx.cs, ascx.cs, aspx.vb ou ascx.vb).

As classes parciais permitem que o código-fonte de uma única classe, estrutura ou interface seja escrito em dois ou mais arquivos físicos dentro de um namespace. Posteriormente o compilador une essas definições parciais para formar uma única declaração para cada tipo. Embora as classes parciais continuem sendo o mecanismo “de facto” utilizado pelo Visual Studio para separar claramente o código criado pelo desenvolvedor do código gerado pelo IDE, os desenvolvedores também as aproveitam em módulos code-behind — principalmente quando trabalham em ambientes de equipe.

Como as classes parciais são a norma para aplicativos ASP.NET 2.0+, você deve separar suas classes ASP.NET 1.1 em classes parciais. Se você pular esta etapa, as páginas e controles de usuário continuarão funcionando, mas terá de atualizar as declarações de campo de controle manualmente nos arquivos code-behind quando modificar os controles em uma página (.aspx) ou um controle de usuário (.ascx).

O comando CWA também altera o valor de AutoEvent­Wireup e a maneira como os eventos são declarados e conectados, e eu acho que o impacto disso é importante o suficiente para ser discutido em detalhes. AutoEventWireup é um atributo booleano que especifica se manipuladores de eventos de objeto Page são conectados implicitamente (quando True) ou explicitamente (quando False). No caso de páginas, AutoEventWireup é definido na marca @Page; para controles de usuário, AutoEventWireup é definido na marca @Control. O comando CWA define AutoEventWireup como True para páginas e controles de usuário em C# e como False para páginas e controles de usuário em Visual Basic .NET.

Os desenvolvedores têm diferentes preferências, e é bem possível que algumas páginas ou controles de usuário do seu aplicativo ASP.NET 1.1 definam AutoEventWireup como True ou False — ou que não o especifiquem de nenhuma forma; nesse caso, o padrão vem de web.config ou, se não estiver especificado ali, de machine.config. É importante saber que o valor de AutoEventWireup pode ser alterado após a execução do comando CWA. Essa alteração pode gerar um comportamento imprevisto, como eventos de página ativados duas vezes. Isso acontece com mais frequência se você criou sua própria convenção de nomenclatura para eventos de objeto Page no aplicativo ASP.NET 1.1. Por exemplo, considere este código C#, em que um manipulador Page_Load2 está conectado ao evento delegado Page.Load:

this.Load += new System.EventHandler(this.Page_Load2);

Quando AutoEventWireup for False, o evento será ativado uma vez, conforme esperado — mesmo que haja uma função code-behind chamada Page_Load. No entanto, quando AutoEventWireup é True, os dois eventos são ativados — uma vez para o código conectado explícito mostrado aqui e uma vez para o código conectado implícito que assina os manipuladores de eventos Page_Load para o evento Page.Load. Considere o código na Figura 9.

Figura 9 Testando o comportamento de AutoEventWireup

public partial class _Default : System.Web.UI.Page
{
  override protected void OnInit(EventArgs e)
  {
    InitializeComponent();
    base.OnInit(e);
  }

  private void InitializeComponent()
  {
    this.Load += new System.EventHandler(this.Page_Load2);
  }

  protected void Page_Load()
  {
    Response.Write("In Page_Load().<br />");
  }

  protected void Page_Load2(object sender, EventArgs e)
  {
    Response.Write("In Page_Load2().<br />");
  }
}

O código na Figura 9 gera esta saída:

In Page_Load().
In Page_Load2().
Top of Form 1
Bottom of Form 1

O mesmo acontece no Visual Basic .NET quando AutoEventWireup está definido como True. Considere o código a seguir:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

  Response.Write("In Page_Load.<br />")

End Sub

Private Sub Page_Load2(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles MyBase.Load

  Response.Write("In Page_Load2.<br />")

End Sub

Quando AutoEventWireup é True, os dois manipuladores de eventos são ativados, fazendo com que a página seja exibida:

In Page_Load2.
  In Page_Load.

Você pode ver que não somente os dois manipuladores de eventos são executados, mas também a ordem em que isso acontece — assim como ocorre com todos os delegados multicast — pode não ser a esperada. Para terminar, observe que, quando AutoEventWireup é True, os manipuladores de eventos de página com o nome de função próprio, como Page_Load, são ativados independentemente de estarem definidos com ou sem argumentos. Por exemplo:

protected void Page_Load()
  {
    Response.Write("In Page_Load().<br />");
  }

é o mesmo que:

protected void Page_Load(object sender, EventArgs e)
  {
    Response.Write("In Page_Load().<br />");
  }

Se os dois estiverem presentes, somente o que possui argumentos será iniciado — outro problema a ser considerado ao solucionar problemas. Portanto, de uma forma geral, seja cauteloso ao testar páginas e controles de usuário, principalmente se a configuração AutoEvent­Wireup foi alterada pelo comando CWA.

Por último, o comando CWA remove o código C# e Visual Basic .NET explícito que conecta eventos de controle e, no lugar dele, usa atributos de eventos declarativos na marcação da página ou do controle de usuário. Por exemplo, no ASP.NET 1.1, um evento de clique em um botão normalmente teria um manipulador de eventos em code-behind, como o seguinte:

this.MyButton.Click += new System.EventHandler(this.MyButton_Click);

O comando CWA remove o manipulador e, no lugar dele, adiciona um atributo OnClick à declaração de controle de servidor, como segue:

<asp:Button ID="MyButton" runat="server" Text="MyButton" onclick="MyButton" />

No Visual Basic .NET, não são adicionados eventos declarativos. Em vez disso, a palavra-chave Handles é adicionada ao code-behind. Portanto, a marcação para um controle Button será exibida da seguinte maneira:

<asp:Button ID="MyButton" runat="server" Text="Button" />

enquanto o code-behind conecta o controle ao manipulador:

Protected Sub MyButton_Click(
  ByVal sender As Object, ByVal e As EventArgs) _
Handles MyButton.Click

End Sub

Os eventos delegados referentes a essas construções de manipuladores de eventos declarativos são criados em tempo de compilação.

Compilar e corrigir Agora a migração está concluída. Recomendo que você recompile a solução e repasse o exercício de corrigir quaisquer erros ou avisos de compilação restantes que eventualmente tenha recebido. Observe que é necessário corrigir os erros de compilação para poder compilar o projeto Web com êxito e visualizar o site migrado em um navegador. Você também deve resolver os avisos de compilação, mas eles não são considerados críticos e não o impedirão de usar o aplicativo Web. Por fim, tome nota de todas as mensagens do compilador porque geralmente elas trazem recomendações úteis de aprimoramentos que você deve considerar implementar assim que tiver tempo disponível. Além dos erros e avisos, é importante fazer testes de regressão e de controle de qualidade com o código migrado e assegurar que os eventos sejam iniciados como esperado.

Considerações pós-migração

Como agora o seu projeto ASP.NET está direcionado para uma estrutura mais recente e executando sob uma versão mais moderna do IDE, você deve estar ciente de alguns aspectos adicionais.

Se você migrou sua solução ASP.NET 1.1 de um sistema operacional de 32 bits para um de 64 bits, observe que o IIS 6.0 e suas versões posteriores dão suporte aos modos de operação de 32 bits e 64 bits. Como o ASP.NET 1.1 só pode ser executado no modo de 32 bits, talvez você ache que o aplicativo ASP.NET convertido ainda tem dependências de 32 bits (como chamadas COM ou P/Invoke) que talvez não continuem funcionando corretamente após a migração. Para corrigir isso, acesse as Configurações Avançadas do Pool de Aplicativos do seu aplicativo e defina o valor de Habilitar Aplicativos de 32 Bits como True.

O Visual Studio 2010 espera que as páginas Web sejam compatíveis com XHTML. Provavelmente suas páginas do ASP.NET 1.1 não são. Por isso, a maioria das páginas mostrará avisos de validação de XHTML (para vê-los, exiba a página no modo de origem ou de design e, em seguida, acesse o menu Exibir e selecione Lista de Erros). Apesar de esses avisos não impedirem que uma página seja executada, eles indicam que as páginas podem não ser renderizadas corretamente em navegadores modernos. Se houver tempo, atualize suas páginas e seus controles de usuário para que sejam compatíveis com XHTML, o que assegurará que eles sejam renderizados corretamente em navegadores modernos. Se o aplicativo Web for direcionado especificamente para um navegador mais antigo, ou se você não quer ser incomodado com erros de validação de marcação agora, é possível alterar como a marcação é validada; para isso, vá até o menu Ferramentas, escolha Opções e acesse o nó Editor de Texto; em seguida, mude o Destino para Internet Explorer 6 (veja a Figura 10). Esse método só é adequado para desenvolvedores que precisam direcionar para o Internet Explorer 6, como deve ser o caso se o seu aplicativo é um aplicativo de intranet corporativa, por exemplo. Isso efetivamente define a validação de renderização em um nível semelhante ao que você provavelmente usava no Visual Studio 2003.

image: You Can Suppress XHTML Validation Errors by Changing the HTML Validation Target to Internet Explorer 6

Figura 10 É possível suprimir os erros de validação de XHTML alterando o destino de validação de HTML para o Internet Explorer 6

No caso dos aplicativos que terão de ser exibidos corretamente em navegadores que não sejam o Internet Explorer ou em versões do Internet Explorer posteriores à 6, você deve continuar exibindo os erros de marcação XHTML no editor de HTML e fazer uso do novo parâmetro de configuração controlRenderingCompatibilityVersion do .NET Framework 4, disponível como propriedade na seção Web.config system.web:

<system.web>
  <pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>

Se controlRenderingCompatibilityVersion não estiver definido em Web.config, o padrão será a versão em execução do ASP.NET. Todavia, quando você especifica o valor de controlRenderingCompatibilityVersion, pode defini-lo como “3.5” ou “4.0” (o Assistente de Conversão o define como “3.5”, que renderiza as páginas da mesma forma que no ASP.NET 3.5). Essa configuração determina como a marcação especificada nos arquivos .aspx é renderizada no navegador. Para citar um exemplo da Ajuda online do Visual Studio 2010, quando controlRenderingCompatibilityVersion for configurado como “3.5”, um controle Label do ASP.NET no lado do servidor com sua propriedade IsEnabled definida como false renderizará um elemento de extensão HTML com o atributo “disabled” definido como “disabled”; quando controlRenderingCompatibilityVersion for configurado como “4.0”, o elemento de extensão resultante incluirá um atributo “class” com uma referência a uma classe CSS.

É importante saber que o uso da configuração “4.0” gera uma marcação XHTML moderna — e isso pode danificar o script de cliente ou as regras de CSS que funcionavam corretamente na versão da página em ASP.NET 1.1, afetando assim o comportamento e/ou a estética do conteúdo renderizado. Desse modo, até você estar totalmente comprometido com a geração de um XHTML válido, sugiro que defina o valor de controlRenderingCompatibilityVersion como “3.5”. E, se você usar a configuração de “3.5”, precisará conhecer xhtmlConformance (somente aplicável se controlRenderingCompatibilityVersion estiver definido como “3.5”), que pode ser definido como “Herdado”, “Estrito” ou “Transicional” (o valor padrão). “Estrito” renderiza na marcação XHTML 1.0 Estrito; “Transicional” renderiza na marcação XHTML 1.0 Transicional; “Herdado” renderiza o HTML de forma parecida (mas não necessariamente igual) ao modo como ele era renderizado no ASP.NET 1.1:

<system.web>
  <pages controlRenderingCompatibilityVersion="4.0"/>
  <xhtmlConformance mode="Transitional"/>
</system.web>

Pela minha experiência, você deve evitar o modo “Herdado”, uma vez que ele pode interferir no funcionamento adequado do UpdatePanel do ASP.NET AJAX. além disso, o valor de controlRenderingCompatibilityVersion não altera o DOCTYPE da sua página Web — ele só altera a forma como os controles ASP.NET se renderizam. Portanto, a correta renderização das suas páginas se deve em grande parte à combinação dos valores de controlRenderingCompatibilityVersion, xhtmlConformance e DOCTYPE, bem como ao tipo de navegador de destino e à versão utilizada.

Outro ponto a ser considerado: Talvez você queira alterar o diretório virtual em que executa o seu site recém-migrado — principalmente se planeja executá-lo em paralelo à versão ASP.NET 1.1. Para isso, no Gerenciador de Soluções, clique com o botão direito do mouse no projeto Web, escolha Propriedades e acesse a guia Web. Em Servidores, você verá uma opção para Usar Servidor Web do ISS Local. Verifique se essa opção está selecionada, especifique a URL do Projeto (como http://localhost/mysitemigrated) e clique no botão Criar Diretório Virtual se o diretório virtual não existe.

Os aplicativos ASP.NET 1.1 utilizam o usuário ASPNET Windows para atribuir privilégios em arquivos e pastas da raiz virtual. O ASP.NET 2.0+ utiliza o usuário SERVIÇO DE REDE. Se o seu aplicativo requer que ASP.NET tenha acesso de gravação a certos arquivos ou pastas, por exemplo, é importante conceder esses direitos ao usuário SERVIÇO DE REDE. Caso não tenha certeza sobre que usuário precisa ter esse acesso, você poderá ver o nome dele examinando o valor da propriedade Environment.UserName ao executar um aplicativo ASP.NET.

Se você utiliza complementos ou dependências de terceiros (sejam binários ou de código-fonte), convém consultar o fornecedor para se certificar de que possui a versão mais recente. Por exemplo, o conhecido programa de log NLog oferece as compilações de biblioteca 1.1 e 2.0. Escolha a compilação 2.0 e faça um esforço para migrar o código 1.1 você mesmo. Além disso, os fornecedores disponibilizarão atualizações para complementos de produtividade projetados para o IDE do Visual Studio. Certifique-se de obter as versões mais recentes desses produtos para o novo IDE do Visual Studio 2010.

Depois de migrar seus aplicativos Web ASP.NET 1.1, você perceberá dois benefícios imediatos. O primeiro deles é que você não precisará mais das Extensões de Servidor do Front Page (FPSE) para ativar o seu site (a menos que queira continuar a usá-las). O segundo benefício é que o IIS não precisará mais ser instalado no computador de desenvolvimento, pois o Visual Studio 2010 tem seu próprio Servidor de Desenvolvimento ASP.NET interno. E, embora você possa continuar executando aplicativos ASP.NET do Visual Studio 2003 lado a lado com aplicativos ASP.NET do Visual Studio 2010 (para fins de controle de qualidade/depuração, por exemplo), o aplicativo ASP.NET convertido do Visual Studio 2010 não precisará mais do Visual Studio 2003 nem de acesso ao .NET Framework 1.1.

 Se você é desenvolvedor em C#, poderá perceber que os eventos de página e de controle de usuário não aparecem mais na janela Propriedades como um ícone de raio amarelo quando exibidos no modo de design. Para exibir/criar esses eventos como no Visual Studio 2003, você terá de clicar com o botão direito do mouse na página (.aspx) ou no controle de usuário (.ascx), no Gerenciador de Soluções, e escolher Exibir Designer de Componentes. Nesse momento, você verá uma janela Propriedades, que contém a conhecida lista de eventos. Clique duas vezes em qualquer um dos eventos da lista para criar um procedimento de evento e delegar código conectado (que é adicionado à função InitializeComponent).

Quando chegar o momento de hospedar o site, você precisará saber qual é o CLR necessário. Quando você usa o .NET Framework 3.0 e 3.5, está executando no CLR 2.0; quando usa o .NET Framework 4, está executando no CLR 4.0. A empresa de hospedagem deve dar suporte ao CLR 4.0 para poder hospedar a sua solução ASP.NET 4.0.

Espero tê-lo ajudado na transição dos seus aplicativos ASP.NET do Visual Studio 2003 para o Visual Studio 2010. Depois que você concluir o processo, terá todo um mundo novo de tecnologias de programação ao seu dispor. Creio que esta é uma decisão de tecnologia relativamente indolor que você nunca se arrependerá de ter tomado.

Jonathan Waldman escreve para a PC Magazine e é um Microsoft Certified Professional sênior que aproveita as tecnologias .NET Framework para criar apaixonadamente soluções de software personalizadas para a área de trabalho e a Web. Você pode entrar em contato com ele pelo email jonathan.waldman@live.com.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Scott Hanselman