Lista de verificación previa a la migración de .NET Framework a .NET

· Actualizado el: · · .NET, .NET Framework, C#, Modernización, Desarrollo en Windows, Migración

Descargar la lista de verificación en Excel (con hojas en japonés e inglés)

Este archivo tiene una estructura de dos hojas, Checklist-ja y Checklist-en, y condensa la lista de verificación previa del capítulo 13 en 34 puntos repartidos en 7 categorías: política / preparación del lado actual de .NET Framework / selección de tipo de aplicación y tecnología / API no compatibles y de atención especial / dependencias exclusivas de Windows / shared library y acceso a datos / operación y build. Las columnas Status y Notes quedan vacías, así que puede usarse tal cual como tabla de inventario para cada proyecto. Si le echa un vistazo antes de leer el artículo, le resultará más fácil seguir el hilo hasta el capítulo 13.

Cambiar el TargetFramework del .csproj a net10.0, actualizar unos cuantos paquetes NuGet y, en cuanto la compilación pase, terminar.

Si la migración fuera así, sería bastante tranquila. En la práctica, lo más habitual es que no lo sea.

En los proyectos reales de .NET Framework suelen dormir varios supuestos de los que normalmente no somos conscientes: System.Web, WCF, Web Forms, un packages.config antiguo, web.config.install.xdt, DLL nativas, COM/ActiveX, controles de terceros que solo funcionan en tiempo de diseño, una suposición implícita de x86, ResX dependientes del diseñador, serializadores antiguos, y más.

Por eso, lo verdaderamente importante en la migración de .NET Framework a .NET es el inventario previo a entrar en la implementación. Si se logran descomponer los puntos en cuestión antes de empezar, la migración deja de ser «una gran apuesta» y pasa a ser «un trabajo de ir resolviendo uno por uno».

En este artículo se resume qué se debe verificar antes de migrar una aplicación empresarial existente en .NET Framework 4.x al .NET actual. El público objetivo principal es el siguiente:

  • Bibliotecas de clases
  • Aplicaciones de consola
  • Servicios de Windows
  • WinForms / WPF
  • ASP.NET Framework (MVC / Web API / Web Forms)
  • Aplicaciones que usan WCF
  • Aplicaciones que usan EF6

La fecha de redacción es el 15/03/2026. Los periodos de soporte y las recomendaciones de las herramientas oficiales cambian, así que si lee este artículo mucho después de esa fecha, verifique también la información oficial.

1. Conclusión inicial

Primero, dejamos aquí solo las conclusiones difíciles de dejar de lado.

  • Lo primero es ordenar el lado de .NET Framework antes de migrar. La guía oficial de Microsoft también recomienda que, antes de portar, se suba a .NET Framework 4.7.2 o posterior, se termine la conversión a PackageReference, la conversión al estilo SDK y la actualización de dependencias.
  • La dificultad depende más del modelo de aplicación que de la cantidad de código. Las bibliotecas de clases y las aplicaciones de consola suelen ser relativamente ligeras, mientras que ASP.NET Framework, Web Forms, el servidor WCF y WF (Workflow Foundation) tienden a ser pesados.
  • WinForms / WPF pueden migrarse a .NET, pero siguen siendo exclusivos de Windows. Si se malinterpreta este punto, se pisa la mina clásica de haber migrado y aun así no poder desplegar en un contenedor Linux.
  • ASP.NET Framework → ASP.NET Core es, en la práctica, una migración de arquitectura. En una aplicación pequeña a veces se puede hacer de una sola vez, pero en un sistema grande de producción es más seguro asumir de entrada una migración por etapas.
  • WCF y EF6 a veces se pueden separar de la migración del runtime. El cliente WCF cuenta con paquetes compatibles para .NET, y EF6 puede migrarse a EF Core de forma independiente después de pasar a .NET moderno.
  • Por otro lado, la creación de AppDomain, .NET Remoting, CAS (Code Access Security, seguridad de acceso al código), COM+, Workflow Foundation y la dependencia de BinaryFormatter son señales de alarma. Si no se detectan a tiempo, el esfuerzo se dispara más adelante.
  • packages.config / install.ps1 / XDT (XML Document Transform, el mecanismo que transforma web.config y similares) / los activos de content / las DLL nativas / COM / ActiveX / la suposición de x86 suelen fallar en tiempo de ejecución o de diseño aunque la compilación pase, por lo que hay que revisarlos antes de empezar.
  • A fecha de marzo de 2026, .NET 10 es la versión LTS. Para un nuevo destino de migración, lo natural es tomar como referencia básica la LTS vigente.
  • Una migración sin pruebas, medición ni un plan de reversión preparado es peligrosa. La migración es, más que un trabajo de implementación, un trabajo de hacer visible una a una las condiciones previas.

2. Antes de nada, decidir si realmente hay que migrar ahora

Lo primero que hay que decidir no es «cómo migrar», sino si realmente conviene migrar esta aplicación ahora.

Si este punto queda ambiguo, se tiende a caer en migraciones técnicamente correctas pero excesivamente pesadas desde el punto de vista del negocio, o, en sentido contrario, en posponer demasiado una migración que claramente convendría hacer.

2.1 Permanecer en .NET Framework también es una decisión perfectamente válida

.NET Framework 4.8.1 sigue recibiendo soporte continuo mientras se ejecute sobre una versión de Windows compatible. Es decir, no se trata simplemente de que haya un peligro inmediato si no se pasa todo a .NET moderno ahora mismo.

Sin embargo, permanecer tiene limitaciones claras.

  • No se puede salir de la exclusividad de Windows.
  • Se sigue arrastrando ASP.NET Web Forms u otras pilas de servidor antiguas.
  • Es difícil beneficiarse de las mejoras de rendimiento, las funciones de lenguaje y el ecosistema del nuevo .NET.
  • Es fácil quedar desalineado con los supuestos actuales de nube, contenedores y CI/CD.

Por el contrario, si existe una dependencia fuerte de lo siguiente, es razonable mantenerse por ahora en .NET Framework 4.8.1 con una operación estable, mientras se traza un plan de sustitución en otra línea de trabajo.

  • Hay una gran cantidad de pantallas construidas en Web Forms.
  • Es necesario mantener estrictamente la compatibilidad del servidor WCF.
  • Hay una dependencia profunda de Workflow Foundation o COM+.
  • Los componentes de terceros en tiempo de diseño no son compatibles con .NET moderno.
  • No se permite un cambio de especificación grande desde el punto de vista del negocio.

2.2 Qué cambia según la opción elegida

Opción Qué mejora Qué queda / qué se pierde Casos adecuados
Permanecer en .NET Framework 4.8.1 Es fácil mantener una operación estable sin romper los activos existentes Exclusividad de Windows, modelo de aplicación antiguo, límites de la modernización Cuando hay una dependencia legada fuerte y ahora se prioriza el negocio con una operación estable
Migrar a .NET moderno pero permanecer en Windows Se puede modernizar el runtime y la cadena de herramientas. Los beneficios de rendimiento, experiencia de desarrollo y estilo SDK son grandes La dependencia de la API de Windows permanece. No se vuelve multiplataforma Aplicaciones empresariales que usan WinForms / WPF, Windows Service o la API de Windows
Migrar a .NET moderno contemplando también, a futuro, Linux / contenedores / la nube Aumenta la libertad del destino de despliegue. También es más fácil renovar el modelo de operación Es necesario retirar antes la API exclusiva de Windows y el modelo de aplicación Cuando se quiere orientar el lado servidor hacia la nube o renovar también la infraestructura

Lo importante no es si se quiere migrar, sino decidir antes dónde se quiere aterrizar después de la migración.

3. Cuatro directrices que conviene decidir de antemano

3.1 La versión de .NET de destino

En el momento de escribir esto, según la política de soporte de Microsoft, .NET 10 es la versión LTS. Por otro lado, tanto .NET 8 LTS como .NET 9 STS tienen previsto finalizar su soporte el 10/11/2026. Que una STS tenga la misma fecha que una LTS se debe a que el periodo de soporte de las STS se amplió de 18 a 24 meses. Si se cuenta con el supuesto anterior de «una STS dura 18 meses», .NET 9 parecería terminar el 12/05/2026, así que, cuando use una fecha como referencia, verifíquela con la información oficial del ciclo de vida.

Por eso, si a partir de ahora se va a migrar por primera vez desde .NET Framework, lo natural, salvo que haya una razón de peso, es tomar la LTS vigente como destino.

El criterio práctico aquí es sencillo.

  • Para una migración pequeña que se quiera resolver rápido, aterrizar directamente en la LTS vigente.
  • Incluso para un sistema troncal pensado para operar a largo plazo, también conviene tomar la LTS vigente como base.
  • «Por conveniencia de una biblioteca existente, se quiere usar la LTS anterior» es una circunstancia posible, pero hay que decidir viendo la fecha de hasta cuándo recibirá mantenimiento.

3.2 Permanecer exclusivo de Windows o apuntar a futuro a multiplataforma

Esta decisión cambia mucho los puntos que hay que revisar.

  • Si se decide permanecer exclusivo de Windows, se puede tomar la ruta realista de modernizar primero el runtime usando WPF/WinForms y el Windows Compatibility Pack.
  • Si se apunta también a futuro a Linux o la contenerización, es necesario hacer un inventario temprano de las API que asumen Windows, como System.Drawing.Common, el registro, WMI, EventLog, Windows Service, COM y Office Interop.

Si se empieza la migración sin decidir esto, a mitad de camino la conversación se retuerce entre «¿estaba bien fijarse en Windows?» y «no, en realidad queríamos desplegarlo en un contenedor».

3.3 Hacerlo de una vez o migrar por etapas

Hay, a grandes rasgos, tres tipos de migración.

  • Una migración completa cercana a in-place
  • Una migración side-by-side, poniendo lo nuevo y lo antiguo en paralelo
  • Una migración por etapas, avanzando poco a poco por ruta o por biblioteca

En particular, para las aplicaciones de ASP.NET Framework, la guía de Microsoft también recomienda claramente la incremental migration (migración incremental). Si se dan condiciones como no querer detener producción, tener muchas funciones o tener muchas dependencias periféricas, es menos forzado diseñar desde el principio bajo el supuesto de una migración por etapas.

3.4 Qué queda «fuera del alcance de esta migración»

Las migraciones fracasan con facilidad porque se intenta abarcar demasiado.

Por ejemplo, hacer lo siguiente al mismo tiempo suele resultar pesado.

  • .NET Framework → .NET
  • ASP.NET Framework → ASP.NET Core
  • EF6 → EF Core
  • Servidor Windows → contenedor Linux
  • Cambio de la infraestructura de autenticación
  • Cambio de la infraestructura de logs/monitorización
  • Migración de base de datos

Por supuesto, es posible que todo esto sea necesario algún día. Pero si es necesario hacerlo al mismo tiempo es otra cuestión.

En la práctica, suele salir mejor separarlo así:

  1. Primero, modernizar el runtime y la estructura del proyecto.
  2. Sobre esa base, migrar el modelo de aplicación.
  3. Por último, actualizar el ORM, la autenticación, la nube y la monitorización.

4. Los cimientos que hay que preparar antes de empezar

La guía de premigración de Microsoft es bastante práctica. En resumen, se trata de acercar de antemano el proyecto actual de .NET Framework a una entrada moderna, antes de migrar.

4.1 Subir a .NET Framework 4.7.2 o posterior

La guía oficial recomienda apuntar a .NET Framework 4.7.2 o posterior antes de portar el código. La razón es que, incluso cuando .NET Standard no tiene tal cual la API existente, resulta más fácil acercarse a una alternativa de API más nueva.

En la práctica, si es posible, resulta más claro tomar 4.8.1 como referencia.

  • Es lo más directo desde el punto de vista del soporte.
  • Es fácil tratarlo como el punto estable final del lado de .NET Framework.
  • Es fácil establecer la directriz de «ordenar primero el lado actual de Framework».

Qué cambia si se hace esto primero

  • El manejo de bibliotecas compartidas de .NET Standard 2.0 se vuelve más estable.
  • Se puede reducir de antemano el ruido derivado del runtime antiguo.
  • Resulta más fácil distinguir si el origen de un problema de compatibilidad es «la antigüedad de Framework» o «la modernización a .NET».

4.2 Pasar a PackageReference

La guía de premigración recomienda pasar las referencias al formato PackageReference. Hacer esto antes mejora considerablemente la visibilidad de la gestión de dependencias.

Qué cambia al pasar a PackageReference

  • Las referencias de paquetes se concentran en el csproj.
  • Las dependencias transitivas se vuelven más visibles.
  • Los supuestos de restore se alinean con el lado de .NET moderno.
  • Mejora la compatibilidad con la CLI y con CI.

Sin embargo, aquí hay una mina.

Minas típicas

La documentación oficial de NuGet especifica las siguientes limitaciones para la migración de packages.config a PackageReference.

  • La migración integrada de Visual Studio no se puede usar en proyectos ASP.NET.
  • Los paquetes que dependen de install.ps1 / uninstall.ps1 pueden no funcionar como se espera.
  • Los activos de la carpeta content pueden ignorarse.
  • Las transformaciones XDT, como web.config.install.xdt, no se aplican.
  • Los paquetes con una estructura de ensamblados antigua directamente bajo lib pueden no resolverse correctamente.

En otras palabras, es mejor no pensar que se trata solo de cambiar el formato de paquete. En particular, en ASP.NET clásico existía bastante la cultura de reescribir web.config al instalar un paquete NuGet, así que durante la migración es fácil que salgan a la luz supuestos implícitos.

Con qué herramienta convertir

No es solo trabajo manual. Sin embargo, cada herramienta tiene un alcance distinto.

Herramienta Qué puede hacer Requisitos y advertencias
Función de conversión de Visual Studio Se convierte haciendo clic derecho en «Referencias» o en packages.config dentro del Explorador de soluciones y eligiendo Migrate packages.config to PackageReference... Visual Studio 2017 15.7 o posterior. No se puede usar en proyectos ASP.NET ni C++. Si la opción no aparece en el menú, abra primero la restauración de NuGet o el Administrador de paquetes y vuelva a hacer clic derecho
.NET Upgrade Assistant Realiza en conjunto el análisis y la actualización del proyecto En la documentación oficial está marcado como no recomendado, y se indica usar GitHub Copilot Modernización
GitHub Copilot Modernización Ayuda con la evaluación, la planificación, la corrección de código y la verificación. Es el eje de la orientación oficial actual Como se indica en 4.5, requiere Visual Studio, Copilot y código C#
Conversión manual al estilo SDK Se crea un nuevo csproj y se trasladan solo los elementos necesarios En proyectos con pocos archivos, a veces esta es la opción más rápida

La función de conversión de Visual Studio crea una copia de seguridad del proyecto antes de ejecutarse y, al final, genera un informe de conversión (dependencias de primer nivel, dependencias transitivas y problemas de compatibilidad detectados). La documentación describe que, si se desea revertir, hay que restaurar el csproj y el packages.config desde la carpeta de copia de seguridad y ejecutar update-package -reinstall en la consola del Administrador de paquetes.

Es decir, se puede probar de una forma reversible. Para la estimación previa al inicio, lo más rápido es convertir primero un solo proyecto y leer el informe.

4.3 Pasar al estilo SDK

La guía de premigración también recomienda la conversión al formato de proyecto de estilo SDK.

Esto tiene bastante impacto.

Qué cambia al pasar al estilo SDK

  • El csproj se vuelve mucho más conciso.
  • Tiene buena compatibilidad con PackageReference.
  • Facilita el multi-targeting.
  • Facilita acercarse a un CI/CD centrado en dotnet build / dotnet test / dotnet publish.
  • Se acerca a la configuración del lado de .NET moderno, lo que reduce las diferencias en la segunda mitad.

Dicho de otro modo, saltar directamente a .NET moderno manteniendo el csproj antiguo y la gestión antigua de NuGet genera una diferencia demasiado grande.

4.4 Actualizar antes las dependencias

Esto también sigue la guía oficial: hay que acercar las dependencias a la última versión disponible y, si es posible, a una versión compatible con .NET Standard.

El sentido de hacer esto primero

  • Se descubre pronto si «este paquete se puede usar en .NET moderno».
  • Se evita que las dependencias antiguas se conviertan en ruido.
  • Facilita convertir las bibliotecas compartidas a netstandard2.0.
  • Facilita concentrar el trabajo de migración posterior en «portar código».

4.5 Verificar también los requisitos de las herramientas oficiales

A fecha de marzo de 2026, el centro de gravedad de las indicaciones de Microsoft se ha desplazado hacia GitHub Copilot Modernización. En lugar de basarse únicamente en las herramientas de migración tradicionales, encaja mejor con la práctica verlo como un flujo de asistencia integral que incluye la evaluación, la planificación, la corrección de código y la verificación.

No obstante, la documentación actual presupone Visual Studio 2026 o la línea de Visual Studio 2022 con soporte activo, GitHub Copilot y código C#.

Por qué es necesario verificar esto

  • Cambia lo que se puede esperar de las herramientas oficiales.
  • Permite alinear los requisitos de IDE, build agent y extensiones del equipo.
  • Permite decidir no esperar demasiado de la automatización en soluciones VB.NET.

No es raro encontrar proyectos donde se mezcla VB.NET. Por eso, vale la pena verificar desde el principio «hasta dónde puede ayudar la última herramienta oficial».

5. Estimar la dificultad según el tipo de proyecto

La migración suele hablarse en bloque como «de .NET Framework a .NET», pero en realidad es un juego distinto según el tipo de proyecto.

5.1 Una idea aproximada de la dificultad

Tipo Sensación de dificultad Principales puntos a considerar
Biblioteca de clases Baja a media Compatibilidad de API, dependencias, división de targets
Consola / procesos por lotes / algunos Windows Service Baja a media Forma de distribución, dependencias nativas, configuración
WinForms / WPF Media Sigue siendo exclusivo de Windows, el diseñador, la UI de terceros, aspectos en torno a BinaryFormatter
ASP.NET MVC / Web API Media a alta Migración del modelo de aplicación a ASP.NET Core, autenticación, sesión, configuración, DI
ASP.NET Web Forms Alta Gran diferencia en el modelo de pantallas, se presupone la sustitución de la capa de UI
Cliente WCF Media Sustitución de paquetes, contratos, configuración
Servidor WCF Alta ¿CoreWCF o rediseño con gRPC/API HTTP?
Hacer EF6 → EF Core al mismo tiempo Alta El ORM es otra cosa distinta, diferencias de comportamiento, historial de migraciones

5.2 En las bibliotecas de clases, la clave está en cómo trazar el «límite compartido»

Las bibliotecas de clases son relativamente fáciles de migrar. Sin embargo, esto solo se cumple cuando la biblioteca está realmente separada como tal.

Si existen dependencias como las siguientes, la dificultad aumenta.

  • Toca System.Web.
  • Accede directamente a HttpContext.Current.
  • Incluye tipos de WPF/WinForms en su API pública.
  • Depende demasiado de API de Windows como el registro, WMI o EventLog.
  • Depende de AppDomain o de Remoting.

Resulta fácil de entender si se piensa así: si se puede extraer solo la lógica de negocio, es ligero; si arrastra también el modelo de aplicación, es pesado.

5.3 WinForms/WPF son fáciles de migrar, pero siguen siendo exclusivos de Windows

WinForms y WPF se pueden migrar a .NET. Sin embargo, ambos siguen siendo frameworks exclusivos de Windows.

Es peligroso equivocarse aquí con las expectativas.

  • Lo que mejora
    • Se puede adoptar el runtime, el lenguaje y el estilo SDK de .NET moderno.
    • Es fácil acercar el CI/CD y la gestión de paquetes a las prácticas actuales.
    • Es fácil obtener algunas mejoras de rendimiento y mantenibilidad.
  • Lo que no cambia
    • Que sigue siendo exclusivo de Windows.
    • Persisten los problemas de compatibilidad de los controles de UI y los componentes en tiempo de diseño.
    • Los problemas de ActiveX/COM/DLL nativas no desaparecen.

Además, hay casos en los que WinForms/WPF necesitan verificar el impacto de BinaryFormatter. En particular, cuando hay tipos personalizados involucrados en el portapapeles, arrastrar y soltar, ResX o la serialización en tiempo de diseño, el problema tiende a salir a la superficie al subir el target a .NET 9 o posterior.

5.4 ASP.NET Framework no es una «migración de runtime», sino una «migración de modelo de aplicación»

La guía de Microsoft afirma explícitamente que la migración de ASP.NET Framework a ASP.NET Core es non-trivial (nada trivial). Esto no se debe simplemente a que cambien los nombres de las API, sino a que la arquitectura de base es distinta.

Las diferencias suelen notarse en los siguientes puntos.

  • Modelo de hospedaje
  • Canalización de middleware
  • Modelo de procesamiento de solicitudes
  • Sesión/caché
  • Autenticación/autorización
  • Configuración
  • Inyección de dependencias
  • Registro/monitorización

En una aplicación de ASP.NET Framework, esto es lo que conviene verificar primero.

  • Qué ruta/endpoint se puede migrar primero.
  • Si se puede retirar la dependencia de System.Web de la biblioteca compartida.
  • Cómo alinear la autenticación, la sesión, el manejo de excepciones y el registro.
  • Si se va a migrar por etapas sin detener producción.

En especial en las aplicaciones grandes, es más realista pensar desde el principio bajo el supuesto de una incremental migration.

5.5 Con Web Forms no se empieza por «migrar activos», sino por «descomponer responsabilidades»

Web Forms no comparte el mismo modelo de aplicación que ASP.NET Core. Por eso, para la estimación es más seguro no partir del supuesto de que las pantallas se pueden llevar tal cual.

En la práctica, se suele empezar por la siguiente descomposición.

  • Separar la lógica de pantalla de la lógica de negocio.
  • Descomponer las responsabilidades incrustadas en Page/UserControl/ViewState.
  • Trasladar la lógica de negocio y el acceso a datos a una biblioteca compartida.
  • Reconstruir la UI con otro modelo, como Razor Pages, MVC o Blazor.

Es decir, en un proyecto de Web Forms es importante tener antes un plan de descomposición de responsabilidades, no solo la migración del runtime.

5.6 Considerar por separado el cliente WCF y el servidor WCF

Aquí es mejor no meterlo todo en el mismo saco.

Cliente WCF

Para el cliente WCF existen paquetes NuGet compatibles orientados a .NET moderno. Por eso, hay casos en los que si solo se trata del lado que llama a WCF, no es tan pesado como parece.

Servidor WCF

Por otro lado, el lado que hospeda el servicio WCF es otra historia. La guía de Microsoft indica, a grandes rasgos, dos rutas de modernización.

  • Usar CoreWCF para mantener la compatibilidad con los clientes existentes.
  • Acercarse a un RPC/HTTP moderno como gRPC.

Sin embargo, CoreWCF no trae todo WCF tal cual, sino un subconjunto. Es adecuado para mantener la compatibilidad con los clientes existentes, pero se presupone un cambio de código y pruebas.

6. Revisar las tecnologías que no funcionan en .NET o que suelen atascar tal cual

Esto es algo que conviene hacer sin falta antes de empezar. Microsoft cuenta con una lista de tecnologías que funcionaban en .NET Framework pero no funcionan en .NET 6 o posteriores.

6.1 Tecnologías que suelen ser señal de alarma

Tecnología Estado en .NET Cómo abordarla
Creación de AppDomain, como AppDomain.CreateDomain No compatible Pensar el aislamiento con otro proceso, un contenedor o AssemblyLoadContext
.NET Remoting No compatible Rediseñar hacia IPC, HTTP, gRPC, sockets, pipes, etc.
CAS / Security Transparency No compatible como límite de seguridad Pensarlo con separación de permisos a nivel de SO/contenedor
System.EnterpriseServices (COM+) No compatible Separar y sustituir el diseño que asume COM+
Workflow Foundation No compatible Considerarlo como una estimación aparte, incluyendo alternativas como CoreWF
Servidor WCF No funciona tal cual de forma integrada Elegir entre CoreWCF o gRPC
BinaryFormatter A partir de .NET 9, la implementación siempre lanza una excepción Migrar el serializador, auditar ResX/portapapeles/arrastrar y soltar

6.2 AppDomain: «aunque queden algunas API, la creación es otro problema»

Todo lo relacionado con AppDomain es un poco complicado. En .NET sigue quedando parte de la superficie de API, pero no se admite el uso de crear un nuevo AppDomain para aislar.

Por eso, si AppDomain se usaba para los siguientes fines, hace falta rediseñarlo.

  • Aislamiento de complementos.
  • Descarga de código cargado dinámicamente.
  • Aislamiento de código de confianza parcial.
  • Separación de un entorno de ejecución temporal.

Antes de migrar, lo que hay que revisar no es solo si aparece la palabra AppDomain, sino para qué se usaba AppDomain.

6.3 Remoting es «más profundo de lo que parece»

Además de Remoting en sí, también puede entrar dentro del alcance del impacto algo como los delegados asíncronos, por ejemplo las llamadas a BeginInvoke()/EndInvoke() de un delegate. Esto no es Remoting propiamente dicho, pero tampoco es compatible con .NET moderno, así que hay que identificarlo antes de migrar.

Por eso, es más seguro revisar también esto al hacer la búsqueda.

  • System.Runtime.Remoting
  • MarshalByRefObject
  • RealProxy
  • BeginInvoke( / EndInvoke(

6.4 BinaryFormatter sale a la superficie de golpe según la versión de destino

Cuanto más antigua es la base de código, más probable es que BinaryFormatter se esté usando «sin ser consciente de ello».

  • Datos persistidos
  • Caché
  • Almacenamiento de sesión
  • Estado de complementos
  • Portapapeles/arrastrar y soltar
  • ResX
  • Entorno del diseñador de WinForms/WPF

A partir de .NET 9, BinaryFormatter no incluye implementación en el runtime, y la API siempre lanza PlatformNotSupportedException. Es decir, esto no es algo para «pensar después», sino un punto que hay que auditar en cuanto se decide la versión de destino.

6.5 Términos de búsqueda que conviene buscar primero con grep

Antes de empezar, con solo buscar los siguientes términos en toda la solución, el panorama cambia bastante.

System.Web
HttpContext.Current
System.Runtime.Remoting
MarshalByRefObject
AppDomain
BinaryFormatter
ServiceHost
ChannelFactory
System.EnterpriseServices
Workflow
packages.config
web.config.install.xdt
install.ps1
DllImport
AxInterop
Microsoft.Office.Interop

Esto no significa que, en cuanto aparezca uno solo de estos términos, sea un descarte inmediato. Es un mapa para saber qué se puede migrar por la ruta estándar y qué queda en una vía aparte.

Comandos de búsqueda reales

Puede usar rg (ripgrep) o PowerShell, cualquiera de las dos herramientas sirve.

# PowerShell. Busca en conjunto dentro de toda la solución
Get-ChildItem -Recurse -Include *.cs,*.vb,*.config,*.csproj,*.vbproj |
    Select-String -Pattern 'BinaryFormatter|System\.Runtime\.Remoting|MarshalByRefObject|AppDomain\.CreateDomain' |
    Select-Object Path, LineNumber, Line
# ripgrep. Cuando primero se quiere hacer una idea a partir del número de coincidencias
rg -n --stats "BinaryFormatter|System\.Runtime\.Remoting|AppDomain\.CreateDomain" --glob "*.cs" --glob "*.vb"

Qué hacer a continuación si se encuentra algo

La búsqueda es solo la entrada; lo importante de verdad es la decisión que viene después. Para cada término, está definido qué revisar a continuación.

Término encontrado Qué verificar a continuación Punto de resolución
System.Web / HttpContext.Current Si se puede sacar de la biblioteca compartida. Si el lado que llama puede reempaquetarlo en un DTO Retirarlo con la estrategia de 8.5
System.Runtime.Remoting / MarshalByRefObject / BeginInvoke Para qué era la llamada remota: entre procesos, entre máquinas, o simplemente una llamada asíncrona Rediseñar hacia IPC, HTTP, gRPC o algo basado en Task
AppDomain Si solo se usa el nombre del tipo, o si se aísla con CreateDomain Si el fin es el aislamiento, usar otro proceso o AssemblyLoadContext (6.2)
BinaryFormatter Si es necesario leer después los datos escritos. Si no se está usando indirectamente a través de ResX o el portapapeles Migrar a otro serializador y elaborar también un plan de reinterpretación de los datos existentes (6.4)
ServiceHost / ChannelFactory Si es el lado hospedador o el lado cliente Evaluarlo por separado, como en 5.6
packages.config / install.ps1 / web.config.install.xdt Qué se reescribía al instalar La mina de 4.2. Recuperar la configuración de forma explícita
DllImport / AxInterop / Microsoft.Office.Interop Los supuestos sobre la arquitectura de bits y el conjunto de archivos necesarios en tiempo de ejecución A la verificación de bitness de 9.4

Al llegar hasta aquí, se obtiene una lista que no responde a «si se puede migrar», sino a «cuál sigue la ruta estándar y cuál necesita una estimación aparte». Lo que se necesita antes de empezar es exactamente una lista con esta forma.

7. Decidir hasta qué punto aceptar la dependencia exclusiva de Windows

Un malentendido frecuente en las migraciones es pensar que «al pasar a .NET, la aplicación se vuelve multiplataforma». No existe tal magia. Si la aplicación está profundamente ligada a Windows, después de la migración seguirá siendo, con toda normalidad, exclusiva de Windows.

7.1 Migrar manteniéndose exclusivo de Windows es una opción suficientemente realista

Microsoft cuenta con el Windows Compatibility Pack, un medio que permite usar desde .NET moderno muchas de las API de Windows, como el registro, WMI, EventLog, Windows Service o Directory Services.

La existencia de esto tiene un gran peso en la práctica.

  • Se quiere pasar primero a .NET moderno.
  • Pero por ahora no se va a salir de Windows.
  • Por eso, se quiere aceptar por el momento la dependencia de la API de Windows.

En un proyecto con este planteamiento, se convierte en una opción sólida.

El primer objetivo de la migración no tiene por qué ser necesariamente la multiplataforma.

7.2 Sin embargo, la API exclusiva de Windows también es «una deuda que pesará más adelante»

Que exista el Windows Compatibility Pack no significa que todo esté resuelto.

  • Se quiere desplegar en un contenedor Linux.
  • Se quiere ejecutar bajo el supuesto de Kubernetes.
  • Se quiere que los desarrolladores de macOS/Linux ejecuten también el mismo build.
  • En el futuro se quiere reducir las VM de Windows en la nube.

Si existen objetivos como estos, conviene hacer visible desde ahora la dependencia de la API de Windows.

7.3 System.Drawing.Common se malinterpreta con especial facilidad

A partir de .NET 6, System.Drawing.Common es una biblioteca exclusiva de Windows. Si hay código que la usa para procesamiento de imágenes o dibujo de texto, primero hay que decidir por cuál de las dos vías se va a optar.

  • ¿Se va a seguir operando en Windows?
  • ¿Se quiere en el futuro que también funcione en Linux/macOS?

En el primer caso, hay ocasiones en las que se puede dejar tal cual por ahora. En el segundo, es necesario incluir desde el principio en el plan de migración la sustitución por algo como SkiaSharp o ImageSharp.

7.4 Señales representativas de una fijación a Windows

Cuando existen referencias o API como las siguientes, es más seguro estimar bajo el supuesto de que, «al menos al principio, se migrará manteniéndose exclusivo de Windows».

  • Microsoft.Win32.Registry
  • System.Management
  • System.Diagnostics.EventLog
  • System.ServiceProcess
  • System.DirectoryServices
  • System.Drawing
  • DllImport / P/Invoke
  • Referencias COM
  • AxInterop.*
  • Microsoft.Office.Interop.*

8. La dificultad cambia según cómo se extraigan las bibliotecas compartidas

En soluciones de mayor tamaño, no es exagerado decir que el éxito o el fracaso de la migración lo determina cómo se divide el shared library.

8.1 Clasificar primero

Resulta fácil organizar las bibliotecas dividiéndolas, a grandes rasgos, en tres tipos.

  1. Lógica de negocio pura / lógica de dominio
  2. Una capa intermedia con cierta dependencia del modelo de aplicación
  3. Una capa muy pegada a la UI/Web/API de Windows

De estas, la que debe migrarse primero es la 1.

  • Cálculos
  • Evaluación de reglas
  • DTO/contratos
  • Servicios de dominio
  • Transformaciones de datos simples

Si esto se logra extraer de forma limpia, la dificultad baja de golpe.

8.2 netstandard2.0 sigue siendo hoy un puente válido

Según la orientación de Microsoft, si se trata de un shared library que también necesita coexistir con el lado de .NET Framework, lo básico es pensar primero en .NET Standard 2.0.

Aquí hay dos puntos importantes.

  • .NET Framework no admite .NET Standard 2.1.
  • Si se quiere que el shared library sea referenciado tanto desde lo antiguo como desde lo nuevo, 2.0 suele ser la solución realista.

8.3 Qué cambia al pasar a netstandard2.0

Enfoque Cómo cambia Casos adecuados Advertencias
Convertir a netstandard2.0 Es fácil de referenciar tanto desde lo antiguo como desde lo nuevo Lógica de negocio pura, contratos comunes, utilidades No se pueden incluir API propias del modelo de aplicación
Multi-target (por ejemplo, net48;net10.0) Mantiene el código común mientras admite diferencias por entorno Bibliotecas con solo pequeñas diferencias de entorno Aumentan las ramas condicionales y la gestión del build
Pasar directamente a exclusivo de net10.0 A futuro es lo más limpio Capas nuevas que no necesitan coexistir con lo antiguo No se puede referenciar desde .NET Framework

8.4 El modo de compatibilidad no es una solución universal

.NET Standard 2.0 cuenta con un modo de compatibilidad para referenciar bibliotecas de .NET Framework. Sin embargo, esto no es una magia que hace que todo funcione de forma transparente.

Por ejemplo, una biblioteca que presupone una API propia de un modelo de aplicación como WPF resulta, con toda normalidad, difícil. Es decir, aunque se hable de shared library, es importante limitarse solo a las responsabilidades que realmente se pueden compartir.

8.5 En las bibliotecas de ASP.NET, la clave está en si se puede retirar System.Web

Al migrar ASP.NET Framework por etapas, resulta bastante duro si el shared library depende directamente de HttpContext.Current o System.Web.

La estrategia básica en este caso es una de las siguientes.

  • Empujar la dependencia de System.Web fuera de la interfaz.
  • Cambiar para recibir como DTO la información procedente de HttpContext.
  • Usar un adaptador durante el periodo de transición de la migración.
  • Si aun así no es posible, retirarlo por etapas con multi-target.

8.6 Subir las bibliotecas empezando por las hojas (leaf-first)

La guía de incremental migration de ASP.NET indica explícitamente que las bibliotecas de soporte se suben en postorder depth-first, es decir, empezando por las hojas.

Esto es bastante efectivo no solo en Web, sino también en soluciones generales.

  • Como las dependencias ya están subidas primero, la visibilidad de las capas superiores mejora.
  • Es fácil localizar los problemas de compatibilidad.
  • Es fácil probar biblioteca por biblioteca.

9. Hacer inventario de NuGet, dependencias externas y componentes de terceros

Si esto se hace con descuido, es en la segunda mitad de la migración donde más se sufre.

9.1 Resulta fácil organizar las dependencias dividiéndolas en cuatro tipos

  1. Paquetes NuGet públicos
  2. Paquetes privados internos/bibliotecas internas de la empresa
  3. Referencias a DLL locales
  4. COM/ActiveX/DLL nativas/SDK

No basta con mirar solo la 1. Las verdaderamente peligrosas son la 3 y la 4.

9.2 Qué verificar en cada dependencia

Para cada dependencia, se verifica como mínimo lo siguiente.

  • Si tiene como target .NET moderno.
  • Si es compatible con PackageReference.
  • Si no hay problemas con el estilo SDK.
  • Si tiene alguna restricción de x86/x64/ARM64.
  • Si depende de herramientas en tiempo de diseño o extensiones de Visual Studio.
  • Si presupone un script de instalación o una transformación de configuración.
  • Si sigue recibiendo soporte.

9.3 Estimar aparte la UI, los informes y los componentes de terceros en tiempo de diseño

En la migración de WinForms/WPF/ASP.NET, esto tiene bastante impacto.

  • Grillas
  • Motores de informes
  • Componentes de salida a PDF
  • Componentes de gráficos
  • Bibliotecas de UI integradas con el diseñador
  • Envoltorios de ActiveX

Estos elementos involucran no solo el runtime, sino también el soporte en tiempo de diseño. Si en la estimación de la migración solo se mira «si compila», con toda normalidad se pasa por alto algo.

9.4 Revisar siempre las DLL nativas y la arquitectura de bits (bitness)

Aunque en la época de .NET Framework parezca que funcionaba con AnyCPU, en realidad puede depender de cosas como las siguientes.

  • COM fijo en x86
  • ActiveX exclusivo de 32 bits
  • Una versión específica del VC++ Runtime
  • DLL nativas firmadas

Esto no es un problema que surja de repente por modernizar a .NET; simplemente sale a la superficie una limitación que ya existía desde el principio. Precisamente por eso, vale la pena hacerlo visible antes de migrar.

10. Tratar EF6, los serializadores y todo lo relacionado con los datos como un problema aparte

La migración del runtime y el rediseño del acceso a datos o de la serialización suelen funcionar mejor si se tratan, en la medida de lo posible, como problemas separados.

10.1 EF6 → EF Core no es una actualización directa

La propia guía de EF de Microsoft indica que EF Core es una reescritura total de EF6 y que no existe una ruta de actualización directa.

Por eso, en una aplicación que usa EF6, el siguiente orden es realista.

  1. Primero, pasar a .NET moderno.
  2. Ejecutar la aplicación manteniendo EF6 si es necesario.
  3. Después, migrar a EF Core como un proyecto aparte.

No mezclar la migración del runtime con la migración del ORM. Solo con esto, la dificultad baja considerablemente.

10.2 Qué cambia si se mantiene EF6

  • Puntos buenos
    • Se pueden posponer las diferencias de la capa de acceso a datos.
    • Se puede concentrar en la migración de la lógica de negocio y del modelo de aplicación.
    • No se mezclan «las diferencias de comportamiento de EF Core».
  • Advertencias
    • Desde el punto de vista del desarrollo nuevo, EF Core es la opción principal.
    • El uso de EF6 Designer/EDMX tiene otras limitaciones aparte.

10.3 En EF6 basado en EDMX hay que revisar también «el tiempo de diseño»

La documentación de EF6 indica que EF Designer no es compatible de forma directa con proyectos .NET/.NET Standard ni con proyectos de .NET Framework de estilo SDK.

En una aplicación basada en EDMX, es necesario considerar por separado estos tres puntos.

  • Si funciona en tiempo de ejecución.
  • Si se puede usar el Designer.
  • Cómo tratar el código generado.

Si se hace un uso intensivo de EDMX, es más seguro incluir esto en la estimación desde el principio.

10.4 BinaryFormatter y las serializaciones propias suelen ser «dependencias ocultas»

Los serializadores son fáciles de pasar por alto si solo se hace una búsqueda de código.

  • Formato de persistencia
  • Mensajería
  • Caché
  • Contratos antiguos de WCF/SOAP
  • ResX
  • Portapapeles/arrastrar y soltar

Todo esto también involucra la compatibilidad de los datos. Es decir, no basta con verificar simplemente «si se puede compilar»; hay que llegar a comprobar si se pueden leer los datos antiguos.

11. Incluir en el alcance de la migración también la configuración, la distribución, la operación y el CI/CD

El alcance de la migración no es solo el código fuente.

11.1 Archivos de configuración

En el lado de .NET Framework, es habitual que haya bastante contenido cargado en app.config/web.config.

  • Cadena de conexión
  • Sección de configuración personalizada
  • Configuración de endpoint de WCF
  • Redirección de enlace (binding redirect)
  • Diagnóstico
  • Diversas configuraciones de ASP.NET
  • Resultado de las transformaciones aplicadas al instalar paquetes

En el lado de .NET moderno hay situaciones en las que cambia la forma de mantener la configuración y la ruta de carga. Por eso, «los archivos de configuración se dejan para después» es peligroso.

Lo primero que hay que hacer es un inventario de la configuración.

  • Qué hay en el archivo de configuración.
  • Qué es imprescindible al iniciar la aplicación.
  • Qué corresponde a diferencias de entorno.
  • Qué se inyectaba automáticamente mediante NuGet o un instalador.

11.2 Forma de distribución

La forma de distribución también se revisa antes de empezar.

  • ¿Bajo IIS?
  • ¿Como Windows Service?
  • ¿Como tarea programada?
  • ¿ClickOnce/MSI/un instalador propio?
  • ¿Se presupone un servidor on-premise?
  • ¿Cuál conviene más, self-contained o framework-dependent?

Aunque se logre migrar el ejecutable principal, si el mecanismo de distribución y arranque sigue presuponiendo lo antiguo, al final se atasca.

11.3 Registro, monitorización y procedimientos de operación

Todo lo relacionado con la operación también es fácil de pasar por alto.

  • ¿Se presupone el Registro de eventos de Windows?
  • ¿Se consultan los contadores de rendimiento?
  • ¿Monitorización basada en WMI?
  • ¿La cuenta de servicio o los permisos son fijos?
  • ¿Se presupone que el destino del registro es un archivo local?

Es bastante común que, después de la migración, el código funcione pero la operación no pueda mantenerse.

11.4 CI/CD y el agente de build

Antes de migrar, también se verifica lo siguiente.

  • Si se puede instalar en el build agent el SDK de .NET necesario.
  • Qué hacer con las canalizaciones que presuponen nuget.exe/msbuild.exe.
  • Si se va a acercar a algo basado en la CLI de dotnet.
  • Cómo actualizar los trabajos de ejecución de pruebas, cobertura y publicación.
  • Si las plantillas internas o las canalizaciones reutilizables presuponen un formato antiguo.

Que funcione en el entorno local de alguien pero el CI falle es algo típico de las migraciones.

12. Una forma realista de llevar adelante la migración

Teniendo en cuenta los puntos vistos hasta aquí, una forma realista de proceder suele terminar tomando aproximadamente la siguiente forma.

12.1 Primero, ordenar el lado actual de Framework

  1. Acercarse a .NET Framework 4.7.2 o posterior, a ser posible 4.8.1.
  2. Actualizar las dependencias.
  3. Revisar packages.config.
  4. Acercarse, en la medida de lo posible, a PackageReference y al estilo SDK.
  5. Verificar que la aplicación actual funciona correctamente en ese estado.

Con solo hacer esto, las diferencias de la etapa posterior se reducen bastante.

12.2 Rescatar primero el shared library

A continuación, se acerca la lógica de negocio y los contratos comunes a netstandard2.0 o a multi-target. El orden de subida es básicamente leaf-first (empezando por las hojas).

12.3 Cambiar la estrategia de la aplicación principal según el modelo de aplicación

  • Bibliotecas de clases / consola / algunos servicios Es relativamente fácil avanzar de forma directa.
  • WinForms / WPF Se moderniza manteniéndose exclusivo de Windows.
  • ASP.NET MVC / Web API Si es pequeño, de una vez; si es pesado, migración por etapas.
  • Web Forms Presuponiendo la sustitución de las pantallas, trasladar primero la lógica compartida.
  • Servidor WCF Decidir antes si se mantiene CoreWCF o se rediseña con gRPC.

12.4 Respetar el principio de «no hacerlo todo a la vez»

Las combinaciones que en especial conviene evitar son estas.

  • Migración de runtime + sustitución total del ORM
  • Migración de runtime + cambio de la infraestructura de autenticación
  • Migración de runtime + migración total a la nube
  • Migración de runtime + cambio de la infraestructura de monitorización
  • Migración de runtime + renovación del framework de UI

Aunque todo sea necesario, casi siempre sale mejor no apilarlo en el mismo sprint.

12.5 Moverse solo después de establecer pruebas y una línea base

Como mínimo, conviene tener preparado lo siguiente antes de moverse.

  • Pruebas unitarias
  • Pruebas de integración de los flujos de negocio principales
  • Verificación tipo snapshot de las pantallas/API representativas
  • Línea base de rendimiento
  • Método de verificación de los registros principales
  • Procedimiento de reversión

Avanzar en un estado en el que no se puede identificar «qué se rompió» después de la migración es bastante peligroso.

13. Lista de verificación previa al inicio

La dejamos aquí en un formato que se puede pegar tal cual en la gestión del proyecto.

13.1 Política

  • Puede explicar en una frase por qué se migra
  • Está decidido si el destino de esta ocasión es .NET moderno exclusivo de Windows o una futura conversión a multiplataforma
  • Se ha decidido la versión de .NET de destino
  • Está decidido lo que no se incluye en el alcance de esta ocasión (conversión a EF Core, renovación de la autenticación, migración total a la nube, etc.)

13.2 Preparación del lado actual de .NET Framework

  • Se ha acercado a .NET Framework 4.7.2 o posterior, a ser posible 4.8.1
  • Se han actualizado las dependencias hacia versiones más recientes
  • Se ha revisado si existe packages.config
  • Se ha verificado si es posible convertir a PackageReference
  • Se ha verificado si es posible convertir al estilo SDK
  • La aplicación actual puede compilarse, iniciarse y probarse en ese estado

13.3 Tipo de aplicación y selección de tecnología

  • Se ha diferenciado la dificultad según el tipo: bibliotecas de clases, escritorio, Web, WCF, etc.
  • Se entiende que WinForms/WPF seguirán siendo exclusivos de Windows
  • Se entiende que ASP.NET Framework implica una migración del modelo de aplicación hacia ASP.NET Core
  • Se ha incluido en la estimación la sustitución de la capa de UI de Web Forms
  • Se ha evaluado WCF diferenciando el cliente del servidor

13.4 Tecnologías no compatibles y API de atención especial

  • Se ha revisado la dependencia de AppDomain
  • Se han revisado Remoting/MarshalByRefObject/BeginInvoke/EndInvoke
  • Se han revisado CAS/Security Transparency/COM+/WF
  • Se ha revisado la dependencia de BinaryFormatter
  • Se ha revisado la dependencia de System.Web

13.5 Dependencias exclusivas de Windows

  • Se ha revisado el uso del registro, WMI, EventLog, Windows Service y Directory Services
  • Se ha revisado el uso de System.Drawing.Common
  • Se han revisado COM/ActiveX/Office Interop/P/Invoke/DLL nativas
  • Se han verificado las restricciones de x86/x64/ARM64

13.6 Shared library y acceso a datos

  • Se ha clasificado el shared library en lógica de negocio / capa pegada al modelo de aplicación
  • Se ha revisado qué se puede convertir a netstandard2.0
  • Se han revisado las bibliotecas que necesitan multi-target
  • Se ha decidido si se puede migrar primero solo el runtime manteniendo EF6
  • Se ha verificado la dependencia de EDMX/Designer

13.7 Operación y build

  • Se ha hecho el inventario de los archivos de configuración
  • Se ha verificado la forma de distribución (IIS/Service/MSI/ClickOnce, etc.)
  • Se han verificado los supuestos de registro/monitorización/permisos/cuenta de ejecución
  • Se ha verificado si es necesario actualizar el CI/CD y el build agent
  • Se ha elaborado el procedimiento de reversión

14. Resumen

Lo importante en la migración de .NET Framework a .NET no es tanto «con qué comando migrar», sino identificar antes de empezar qué se puede llevar tal cual y qué es un problema aparte.

Si hay que resumirlo en unos puntos, son estos seis.

  • Ordenar el lado de .NET Framework antes de migrar
  • Diferenciar la dificultad según el modelo de aplicación
  • Revisar antes las tecnologías no utilizables
  • Decidir hasta qué punto aceptar la dependencia exclusiva de Windows
  • Decidir cómo dividir el shared library
  • No sobrecargar al mismo tiempo la migración del ORM, la autenticación y la nube

En una migración, la precisión de la estimación cambia bastante en la primera semana. Dicho de otro modo, si en esa semana se logran ordenar los puntos en cuestión, la segunda mitad puede acercarse bastante a un desarrollo normal.

«Primero, probemos a cambiar a net10.0» no está mal como exploración. Sin embargo, como migración de producción, hay puntos que hay que revisar antes de eso. Precisamente eso es lo que se ha ordenado en este artículo.

15. Referencias

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

El artículo está directamente relacionado con los siguientes servicios.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

¿Qué se debe hacer primero antes de migrar de .NET Framework a .NET?
Antes de entrar en la implementación, conviene terminar primero de ordenar el lado de .NET Framework. La guía oficial de Microsoft también recomienda que, antes de portar el código, se suba a .NET Framework 4.7.2 o posterior (en la práctica, a 4.8.1 si es posible), se convierta packages.config a PackageReference, se migre al formato de proyecto de estilo SDK y se actualicen las dependencias hacia versiones más recientes. Hacer esto primero reduce mucho las diferencias de la posterior modernización a .NET y facilita distinguir si el origen de un problema de compatibilidad es «la antigüedad de Framework» o «la modernización a .NET». Junto con esto, antes de empezar también se debe hacer un inventario de tecnologías no compatibles como AppDomain, Remoting o BinaryFormatter.
¿Es posible decidir permanecer en .NET Framework?
Sí, es una decisión perfectamente razonable. .NET Framework 4.8.1 sigue recibiendo soporte mientras se ejecute sobre una versión de Windows compatible, así que no es cierto que haya un peligro inmediato si no se pasa todo a .NET moderno de inmediato. Si se dan condiciones como una gran cantidad de pantallas en Web Forms, la necesidad de mantener estrictamente la compatibilidad del servidor WCF, una dependencia profunda de Workflow Foundation o COM+, o componentes de terceros en tiempo de diseño no compatibles, es razonable mantenerse por ahora en 4.8.1 con una operación estable mientras se traza un plan de sustitución en otra línea de trabajo. No obstante, quedan limitaciones como no poder salir de la exclusividad de Windows y aprovechar con dificultad el rendimiento y las funciones de lenguaje del nuevo .NET.
¿Qué tecnologías no se pueden migrar a .NET o suelen causar problemas?
La creación de AppDomain, .NET Remoting, CAS (Code Access Security, seguridad de acceso al código), COM+ (System.EnterpriseServices) y Workflow Foundation no son compatibles con .NET moderno: son señales de alarma que exigen un rediseño. El servidor WCF no funciona tal cual de forma integrada, por lo que hay que elegir entre rediseñarlo con CoreWCF o con gRPC/API HTTP. BinaryFormatter, a partir de .NET 9, no incluye implementación y siempre lanza una excepción, por lo que se necesita una auditoría que abarque los datos persistidos, los ResX y el portapapeles/arrastrar y soltar. Además, la conversión install.ps1/XDT de packages.config, las DLL nativas, COM/ActiveX y la suposición de x86 son puntos que requieren atención, ya que pueden fallar en tiempo de ejecución aunque la compilación se complete.
¿Migrar una aplicación WinForms o WPF a .NET la convierte en multiplataforma?
No. Aunque WinForms y WPF puedan migrarse a .NET, siguen siendo frameworks exclusivos de Windows. Lo que se obtiene con la migración son beneficios como el runtime de .NET moderno, las funciones de lenguaje, el estilo SDK y la compatibilidad con CI/CD, pero no se logra que la aplicación funcione en un contenedor Linux. Si en el futuro se busca Linux o la contenerización, es necesario hacer un inventario temprano de las API que asumen Windows, como System.Drawing.Common, el registro, WMI, EventLog, Windows Service, COM y Office Interop. Por el contrario, si se opta por seguir siendo exclusivo de Windows, se puede tomar la ruta realista de modernizar primero el runtime con Windows Compatibility Pack.

Perfil del autor

Página de presentación del autor del artículo.

Go Komura

Representante de KomuraSoft LLC

Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.

Volver al blog