Migração de legado · .NET

Migrar do .NET Framework para o .NET moderno: WebForms, WCF e o que realmente muda

Migrar do .NET Framework para o .NET 8 ou .NET 10 não é trocar o número da versão no projeto. Boa parte do código vem junto quase sem mudança — e uma parte específica, previsível, precisa ser reconstruída. Saber qual é qual antes de começar é o que separa uma migração tranquila de uma que trava no meio.

Por NasteSoft Leitura de 13 min

.NET Framework e .NET moderno: o que é o quê

A confusão de nomes não ajuda, então vale fixar os termos. O .NET Framework é a plataforma original, só para Windows, que foi da versão 1.0 até a 4.8.x. A 4.8.1 é a última: não haverá um .NET Framework 5. Ele continua instalado no Windows, é tratado como componente do sistema operacional e segue recebendo correções de segurança junto com ele.

O .NET moderno começou como .NET Core (1.0 a 3.1) e, a partir da versão 5, passou a se chamar só ".NET": 5, 6, 7, 8, 9, 10. É multiplataforma (Windows, Linux, macOS), roda em contêiner, é bem mais rápido e é onde acontece toda a evolução da plataforma, da linguagem C# e das bibliotecas.

As versões pares são LTS (suporte de longo prazo, três anos); as ímpares têm suporte mais curto. Hoje, as LTS que importam são o .NET 8, lançado em novembro de 2023, cujo suporte termina em novembro de 2026, e o .NET 10, lançado em novembro de 2025, com suporte até novembro de 2028. Por isso, quem pesquisa "migrar .NET Framework para .NET 8" deveria, num projeto que começa agora, mirar o .NET 10. Quem já migrou para o .NET 8 sobe para o 10 com um esforço pequeno, nada parecido com o salto que vem do Framework.

O Framework não vai parar amanhã

Um sistema em .NET Framework 4.8 não deixa de funcionar numa data marcada. O custo de ficar é outro: bibliotecas que só lançam versões novas para o .NET moderno, desempenho, hospedagem em Linux e contêiner, recursos novos de C# e uma oferta cada vez menor de quem queira trabalhar com WebForms. É um custo que cresce devagar, até o dia em que uma dependência obriga a mudar às pressas.

O que migra quase direto

A boa notícia é real: o C# é o mesmo, a maior parte da biblioteca base é a mesma, e muito código de negócio compila no .NET moderno com ajustes pequenos. Costumam vir quase direto:

  • Bibliotecas de classe com regra de negócio que não dependem de System.Web, de WCF ou de APIs exclusivas do Windows. O passo intermediário clássico é levá-las para netstandard2.0, que o Framework 4.8 e o .NET moderno conseguem consumir ao mesmo tempo.
  • Aplicações console e serviços Windows — estes viram um Worker Service, que pode continuar rodando como serviço do Windows.
  • WinForms e WPF, que existem no .NET moderno desde o .NET Core 3.0. Continuam só para Windows, e o que costuma dar trabalho são os componentes visuais de terceiros sem versão compatível, não o código das telas.
  • ASP.NET MVC 5 e Web API 2, cujo modelo de controllers é parecido com o do ASP.NET Core. Há trabalho — rotas, filtros, injeção de dependência, autenticação, web.config virando appsettings.json e Global.asax virando Program.cs com middleware —, mas é trabalho de adaptação, não de reescrita.
  • Acesso a dados com ADO.NET ou Dapper, que funciona igual, trocando-se apenas o pacote do provedor quando for o caso.

Ainda assim, "quase direto" pressupõe testes. Mudanças sutis existem — formatação de cultura, serialização, criptografia, codificação de texto — e aparecem justamente em relatório e em integração.

O que precisa ser reconstruído

Aqui está o núcleo de qualquer migração de .NET Framework para .NET 10. Algumas tecnologias simplesmente não existem no .NET moderno, e nenhuma ferramenta converte o seu uso automaticamente.

No .NET FrameworkNo .NET modernoCaminho usual
ASP.NET WebFormsNão existeRazor Pages, MVC ou Blazor — reescrita das telas
WCF (servidor)Não existeCoreWCF, ASP.NET Core Web API ou gRPC
WCF (cliente)Existe, via pacotes System.ServiceModelAjuste de configuração, em geral
.NET RemotingNão existeWeb API, gRPC ou fila de mensagens
AppDomains múltiplosNão é possível criar novosAssemblyLoadContext ou processos separados
System.Web (HttpContext, módulos, handlers)Não existeMiddleware do ASP.NET Core
Entity Framework 6Roda (EF 6.4+), com limitaçõesManter num primeiro momento ou migrar para EF Core
Windows Workflow FoundationNão existeReescrever o fluxo

WebForms

É o caso mais pesado. O WebForms depende de ViewState, postback, controles de servidor e do ciclo de vida da página (Page_Load, eventos de botão, UpdatePanel). Nada disso existe no ASP.NET Core. O Blazor tem um modelo de componentes que lembra o WebForms na superfície, e por isso costuma ser a escolha de quem quer uma transição mais familiar para a equipe — mas cada tela é escrita de novo.

O que decide o tamanho do trabalho não é o número de telas, e sim onde está a regra de negócio. Em muito sistema WebForms ela mora no code-behind: o clique do botão valida, calcula, grava no banco e monta o e-mail. Antes de reescrever a tela, é preciso tirar essa regra de lá e documentá-la — exatamente o mesmo problema dos sistemas Delphi e VB6, e a razão pela qual conversores automáticos de código legado entregam um resultado tão ruim: eles traduzem a tela com a regra dentro.

WCF no .NET Core e no .NET moderno

O lado cliente do WCF existe no .NET moderno, por meio dos pacotes System.ServiceModel.*; consumir um serviço SOAP de terceiros continua possível. O lado servidor não existe. Há três caminhos:

  • CoreWCF — projeto de código aberto que reimplementa boa parte do modelo de serviços do WCF sobre o ASP.NET Core. Faz sentido quando há consumidores externos que você não controla e que esperam o mesmo contrato SOAP. Nem todo binding e nem todo recurso do WCF original estão disponíveis, então a lista do que o seu serviço usa precisa ser conferida.
  • ASP.NET Core Web API (REST/JSON) — o caminho natural quando os consumidores são sistemas seus ou podem ser ajustados.
  • gRPC — bom para comunicação interna entre serviços, com contrato forte e desempenho alto; menos indicado quando o consumidor é um navegador ou um parceiro externo.

Remoting e AppDomain

O .NET Remoting não existe no .NET moderno, e não é possível criar AppDomains adicionais. Sistemas que usavam AppDomain para isolar plugins ou recarregar módulos passam a usar AssemblyLoadContext (para carregar e descarregar assemblies) ou processos separados (para isolamento de verdade). Remoting vira uma API, gRPC ou fila. São partes geralmente pequenas do código, mas centrais na arquitetura — e por isso precisam ser mapeadas cedo.

System.Web

HttpContext.Current, HttpModule, HttpHandler, sessão em System.Web.SessionState: tudo isso sai. O equivalente é o pipeline de middleware do ASP.NET Core, com HttpContext injetado em vez de acessado de forma estática. O ponto perigoso é o código de biblioteca que usa HttpContext.Current lá no fundo, longe da camada web: ele impede que a biblioteca seja reaproveitada e precisa ser desacoplado.

Entity Framework 6 x EF Core

O EF 6 (a partir da 6.4) roda no .NET moderno, o que permite migrar a aplicação primeiro e o acesso a dados depois. Mas o EF 6 não evolui mais, e modelos baseados em EDMX (o designer visual) dão trabalho nos projetos novos. O EF Core é outra biblioteca, não uma versão nova do EF 6: não tem EDMX, trata lazy loading como opção explícita e recusa consultas LINQ que não consegue traduzir para SQL, em vez de avaliá-las silenciosamente na memória. Isso é bom, mas quebra consultas que "funcionavam". Migrar para o EF Core é um passo à parte, com testes de cada consulta relevante.

Ferramentas oficiais e seus limites

O .NET Upgrade Assistant, da Microsoft (extensão do Visual Studio e ferramenta de linha de comando), faz bem a parte mecânica: converte o arquivo de projeto para o formato SDK, troca o framework-alvo, atualiza referências de pacotes NuGet, aplica algumas substituições de API conhecidas e aponta o que não tem equivalente. Também ajuda em parte da passagem de serviços WCF para o CoreWCF. Nas versões recentes do Visual Studio, a Microsoft passou a oferecer ainda a modernização assistida pelo GitHub Copilot, que segue o mesmo princípio de ajudar no trabalho mecânico.

Outras peças úteis:

  • O modo de análise do Upgrade Assistant, que gera um relatório das incompatibilidades antes de qualquer mudança.
  • Os analisadores de compatibilidade do próprio SDK, que avisam sobre APIs que só funcionam no Windows ou que não existem mais.
  • O Windows Compatibility Pack (Microsoft.Windows.Compatibility), que traz para o .NET moderno APIs como registro do Windows, WMI e Event Log — útil para migrar primeiro e limpar depois.

O limite é claro: essas ferramentas não reescrevem WebForms, não redesenham a arquitetura e não sabem qual regra de negócio está escondida em qual evento. Elas reduzem horas de trabalho braçal e mostram o tamanho do problema; não decidem por você o que fazer com ele. Tratar o resultado do Upgrade Assistant como "migração pronta" é o erro mais comum que vemos.

Migração incremental, lado a lado

Para aplicações web grandes, a Microsoft documenta uma estratégia de migração incremental que é a aplicação direta do padrão de estrangulamento — o mesmo que defendemos em toda migração de sistemas legados:

  1. Uma aplicação ASP.NET Core nova fica na frente. Ela recebe todas as requisições.
  2. O YARP, proxy reverso de código aberto da Microsoft, encaminha para a aplicação .NET Framework antiga toda rota que ainda não foi migrada.
  3. Cada rota ou módulo migrado passa a ser atendido pela aplicação nova, e a configuração do proxy deixa de encaminhá-lo. O usuário não percebe a troca.
  4. Os System.Web adapters (pacotes Microsoft.AspNetCore.SystemWebAdapters) cuidam da convivência: oferecem no ASP.NET Core uma API parecida com a do System.Web, para que bibliotecas compartilhadas sigam funcionando nas duas aplicações, e permitem compartilhar sessão e autenticação entre a aplicação antiga e a nova.
  5. Quando nada mais é encaminhado, a aplicação antiga é desligada.

A vantagem é que cada passo é pequeno, entra em produção sozinho e pode ser revertido mudando uma rota. Não existe "virada" de fim de semana. A desvantagem é que, durante um período, são duas aplicações em produção, com o cuidado de manter sessão, autenticação e configuração coerentes entre elas — trabalho que precisa estar no plano, não ser descoberto no caminho.

E o banco de dados?

Na maioria das migrações .NET o banco fica onde está — geralmente um SQL Server — e só o acesso a dados muda. Isso é desejável: trocar a aplicação e o banco ao mesmo tempo multiplica o risco. Mas duas situações pedem atenção:

  • SQL Server muito antigo. Os provedores atuais e as versões novas do SQL Server têm limites de compatibilidade com versões antigas; às vezes o banco precisa ser atualizado antes ou durante o projeto.
  • Regra de negócio dentro do banco. Procedures, triggers e views fazem parte do sistema e precisam ser documentadas como o código, mesmo que permaneçam lá.

Quando a troca de banco faz parte do projeto — sair do Access, de um Firebird ou de um SQL Server 2005 —, ela merece plano próprio. Detalhamos isso em migração de banco de dados legado sem perder dado.

Testes: a rede de segurança que quase nunca existe

Sistemas em .NET Framework raramente têm testes automatizados suficientes. Escrever testes de unidade para tudo antes de migrar é inviável; migrar sem nenhum é imprudente. O meio-termo que funciona:

  • Testes de caracterização nas rotinas críticas: dado esta entrada, o sistema atual produz esta saída. O teste não julga se está certo, só garante que a versão nova faz igual.
  • Comparação de saídas entre a aplicação antiga e a nova para o mesmo conjunto de dados — relatórios, cálculos, arquivos gerados, respostas de API.
  • Testes de contrato nas integrações, principalmente nos serviços WCF que viram CoreWCF ou Web API.

Esses testes nascem da documentação do comportamento atual — por isso vale ler como documentar um sistema legado antes de começar a mexer no código.

Um roteiro que funciona

  1. Inventário: projetos, versões do Framework, pacotes, componentes de terceiros, uso de WebForms, WCF, Remoting, AppDomain e APIs exclusivas do Windows. O modo de análise do Upgrade Assistant ajuda aqui.
  2. Entender e documentar as regras de negócio que estão em code-behind, serviços e banco.
  3. Separar as bibliotecas e levá-las para netstandard2.0 ou multi-target, para que sirvam às duas aplicações.
  4. Montar a aplicação nova na frente, com YARP e System.Web adapters, quando for web.
  5. Migrar por fatias, cada uma com testes de caracterização e comparação de saída, cada uma reversível.
  6. Desligar o legado quando a última rota deixar de ser encaminhada.

Para quem quer entender como isso vira custo e prazo, explicamos os fatores em quanto custa migrar um sistema legado.

Perguntas frequentes

Devo migrar para o .NET 8 ou para o .NET 10?

Para um projeto que começa agora, o .NET 10. As duas são versões LTS, mas o suporte do .NET 8 termina em novembro de 2026, enquanto o .NET 10, lançado em novembro de 2025, tem suporte por três anos. Quem já está no .NET 8 sobe para o .NET 10 com bem menos esforço do que o salto que vem do .NET Framework.

O .NET Framework 4.8 vai parar de funcionar?

Não há data para isso. O .NET Framework 4.8.x é a última versão do Framework, é um componente do Windows e segue recebendo correções de segurança junto com ele. O problema não é parar de funcionar: é não evoluir. Bibliotecas novas, recursos de linguagem, desempenho, contêineres Linux e boa parte do ecossistema moderno ficam fora do alcance.

Dá para converter WebForms para Blazor automaticamente?

Não de forma que valha a pena manter. WebForms depende de ViewState, postback e do ciclo de vida da página, que não existem no ASP.NET Core. Blazor tem um modelo de componentes parecido na superfície, mas a reescrita das telas é necessária. O que se aproveita bem é a regra de negócio, desde que ela seja tirada do code-behind antes.

Meus serviços WCF funcionam no .NET moderno?

O lado cliente, sim: há pacotes System.ServiceModel para consumir serviços WCF a partir do .NET moderno. O lado servidor do WCF não existe no .NET moderno. Os caminhos são o CoreWCF, projeto de código aberto que reimplementa boa parte do modelo de serviços, ou reescrever o contrato como ASP.NET Core Web API ou gRPC. A escolha depende de quem consome esses serviços e de quanto o contrato SOAP precisa ser preservado.

Quanto tempo leva migrar uma aplicação .NET Framework?

Depende muito mais da composição do sistema do que do tamanho. Uma API Web API 2 com bibliotecas bem separadas pode levar semanas; um portal WebForms com regra de negócio no code-behind e serviços WCF expostos para terceiros leva meses, feito por partes. Um diagnóstico curto do código e das dependências é o que permite estimar com honestidade.

Tem um sistema em .NET Framework para migrar?

A NasteSoft e seus parceiros já migraram aplicações .NET, Delphi e VB6 e bancos de dados. Começamos entendendo o sistema — depois escrevemos o código.

Vamos conversar

Seu sistema ainda roda no .NET Framework?

Conte o que ele faz e do que é feito — WebForms, WCF, WinForms, serviços. Respondemos com uma leitura honesta do caminho e do que precisa ser entendido antes.

WhatsApp +55 41 99511-2870 · e-mail rafael.naste@nastesoft.com.br

WhatsApp