Hoy vamos a continuar con el diario de bitácora de la migración de DotNetNuke a la plataforma Azure justo donde lo dejamos después de dejar funcionando el WebSite en local con una base de datos remota en SQL Azure.
El siguiente objetivo era hacer un despliegue del gestor de contenidos en la nube, aunque tal y como estaban estructurados los archivos de proyecto no iba a ser una publicación directa. El principal inconveniente era que el portal está concebido como un WebSite (WSP - Web Site Project) en vez de una WebApplication (WAP - Web Application Project). Los WSP no están soportados en Azure sino los WAP que tengan una clase que herede de WebRole, con lo que había que hacer un trabajo de conversión.
WebSites vs WebApplications
Antes de comenzar con la conversión, lo primero que me vino a la mente fue buscar el motivo de porqué DNN, que estaba actualizado a los últimos Frameworks de .NET y que ha evolucionado acorde con la tecnología, seguía usando un modelo de proyectos que, aún siendo soportado hoy en día, desde 2006 estaba en desuso. Busqué algo de información en los foros y encontré un post con la misma cuestión, y resuelto con estos motivos:
- Porque es más fácil hacer cambios: esto es cierto, ya que no hay que recompilar todo el sitio si se hace una modificación en código, aprovechando las características de compilación dinámica de ASP.NET. Realmente no me preocupaba, ya que esto en Azure "no se puede hacer" y lo tenía asumido. Esto es debido a que no se tiene acceso remoto a las instancias de WebRoles para poder modificarlos (por lo menos hasta que salga el nuevo role de Virtual Machine, pero como expliqué en la introducción, no era mi intención usarlo).
- Por historia: cuando salió en 2006 el modelo de WAP, se había hecho ya mucho esfuerzo en migrar DNN a ASP.NET 2.0 con el modelo WSP, por lo que se decidió seguir con él. Comentan que según Microsoft no hay diferencias significativas de rendimiento y escalabilidad entre los dos modelos. En esto último difiero totalmente. Desde que salió ASP.NET 2.0 en la empresa en la que trabajo estuvimos sufriendo el rendimiento en los proyectos que teníamos como WebSites, sin contar con los problemas de integración con TFS al no tener archivo de proyecto y para qué hablar del infierno de las referencias. Cuando surgió de nuevo el modelo WAP -que existió en VS2003 y que por una mala decisión de Microsoft inicialmente no lo incluyeron cuando salió VS2005-, después de muchas pruebas de stress, rendimiento y comparación entre los dos modelos, decidimos migrar todos los proyectos WSP que teníamos a WAP. Las mejoras fueron notables, no sólo en la integración con nuestras herramientas de control de código fuente y tiempos de desarrollo, sino en los tiempos de compilación y ejecución en producción.
En esta dirección de MSDN podéis ver una comparación de los dos tipos de proyectos por si alguien tiene más interés en el tema.
Finalmente, alguién preguntó en los foros de DNN cómo convertir el proyecto en una WebApplication y se dieron directrices con enlaces a MSDN de cómo llevar a cabo la migración, aunque se advertía que habría que realizar este proceso cada vez que surgiera una actualización.
Asumido.
Convirtiendo el proyecto
Para convertir el proyecto en una WebApplication, hay muchas guías para hacerlo como el enlace de MSDN que puse dos párrafos atrás. Aquí dejo otro enlace de una guía que seguí en su momento para convertir todos los proyectos que teníamos en el trabajo.
Como el objetivo no es escribir un artículo de cómo convertir WSPs en WAPs, sino comentar lo que me encontré en la conversión, detallo todo el proceso que seguí con DotNetNuke.
Paso 1: agregar a la solución un proyecto nuevo tipo WebApplication
La mejor estrategia para migrar un WebSite a un WAP es crear un proyecto en blanco en una carpeta por separado para evitar tener que estar cambiando los ficheros existentes. Para hacerlo:
- Pulsamos con el botón derecho sobre el archivo de solución y seleccionamos el menú "Agregar->Nuevo proyecto".
- Seleccionamos el tipo de proyecto "Aplicación web vacía de ASP.NET" e introducimos, el nombre de proyecto, por ejemplo, "DotNetNuke.WebApplication"
- Una vez creado eliminamos el archivo "web.config" que se añade por defecto. La solución tenía la siguiente pinta:
Paso 2: establecer las referencias del proyecto
El siguiente paso es agregar las mismas referencias que tiene el website a nuestro nuevo proyecto. Para ello:
- Pulsamos botón derecho sobre el WebSite y seleccionamos "Páginas de propiedades". En la seccion de referencias nos anotamos las referencias que usa el website y si son a ensamblados o a proyectos -la técnica del Alt-PrintScreen + Pegar en el paint suele ayudar mucho para ir revisando luego el siguiente paso.
- Vamos añadiendo una a una a nuestro nuevo proyecto todas las referencias. Las que son a ensamblados, hacemos que apunten a la carpeta "bin" del WebSite, para asegurarnos de tomar la misma versión.
- Luego compilamos el proyecto y verificamos que todas las referencias están funcionando correctamente
Uno de los problemas que me encontré fue que el proyecto WebApplication que acaba de agregar tenía configurado como Framwork destino el 4.0. Al añadir referencias de proyecto de otra versión de Framework, salta una advertencia indicando que no es posible combinar distintos motores en tiempo de ejeucución y que la referencia iba a ser de archivo. Para no tener problemas, reconfiguré el WebApplication a Framwork 3.5 que es el mismo que el que tienen los proyectos del DNN, aunque más adelante cuando publiqué en Azure las establecí todas a 4.0 -esta última explicación la dejo para el capítulo correspondiente.
Paso 3: copiar los ficheros desde el WebSite al nuevo proyecto WebApplication
El siguiente paso en la migración es copiar los archivos del proyecto WebSite a nuestra WebApplication. Para esta tarea, la solución más sencilla es copiar y pegar todos los ficheros dentro de nuestro proyecto. Hay que tener en cuenta que en este punto todavía los ficheros no han sido convertidos y la estructura de carpetas es similar a la que está en el proyecto WebSite.
En este momento, tenemos la WebApplication con una copia de todos los archivos del WebSite. Hay que tener en cuenta que una de las diferencias de los dos tipos de proyectos es que el IDE de Visual Studio crea dinámicamente una clase parcial para cada página con la extensión ".designer.vb", lo que permite tiempos de compilación mucho más rápidos. En este momento los ficheros no tienen esta clase parcial generada, además de que se puede observar que en los tags de declaración de los archivos con extensión aspx|ascx|master que se sigue usando el tag "CodeFile" en lugar del "CodeBehind".
Hay que tener en cuenta que se puede tener una WebApplication con mezcla de estas dos técnicas (yo denominaría esta técnica WSAP! o "Web Site Application Projects") en los que podemos tener páginas con CodeFile para aquellas que querramos modificar en el entorno de producción sin tener que recompilar toda la aplicación. Yo utilizaría estas páginas como excepción, no como norma, debido al rendimiento de las mismas así como muchos otros factores ya comentados.
Paso 4: convertir los archivos del proyecto
Para generar todas estas clases parciales seguimos un sencillo proceso:
- Pulsamos con el botón derecho sobre el nodo de la WebApplication y seleccionamos el comando "Convertir en aplicación web"
Tras unos minutos -el proyecto tiene bastantes archivos- esta acción hará que se examine recursivamente cada página, control de usuario y página maestra en el proyecto, generando automáticametne el fichero .designer.vb sociado a cada una de ellas, además de cambiar el atributo "CodeFile" por el "CodeBehind".
Además, se renombrará la carpeta App_Code por Old_App_Code para evitar la doble compilación de los archivos que estén en dicha carpeta. Si se dejara el mismo nombre de carpeta la clase sería compilada dos veces, una durante la compilación del proyecto y otra dinámicament en tiempo de ejecución, lo que resultaría en errores típicos de "no se pudo cargar el tipo". En nuestro caso, los dos únicos archivos que estaban en dicha carpeta "Global.asax.vb" y "AssemblyInfo.vb" fueron reubicados a sus carpetas correspondientes (en el root y en "My Project").
Paso 5: añadir espacios de nombres
El último paso antes de comenzar a ejecutar es corregir los errores que nos han surgido en la ventana de Lista de Errores. El más repetitivo de todos ellos es el del problema con los espacios de nombres.
Hay que tener en cuenta que los archivos que hemos copiado del WebSite por defecto no tiene un espacio de nombres a no ser que se indíque explícitamente en código. Esto es obvio ya que no existe archivo de proyecto. Para evitar este error y respetar los mismos espacios de nombres que tenía el WebSite, quitaremos el espacio de nombres del WebApplication:
- Pulsamos con el botón derecho sobre el nodo del WebApplication y seleccionamos "Propiedades". En la pestaña "Aplicación" dejamos en blanco la caja de texto "Espacio de nombres raíz".
Del mismo modo, puede que se hayan añadido espacios de nombres en el WebSite que no hayan sido contemplados en nuestro nuevo WebApplication. Para agregar estos espacios de nombres:
- Abrimos el archivo web.config y buscamos la cadena de texto "<namespaces>", anotando todos los espacios de nombres
- Pulsamos con el botón derecho sobre el nodo del WebApplication y seleccionamos "Propiedades". En la pestaña "Referencias", agregamos todos los espacios de nombres que estaban en el paso anterior
Paso 6: compilar y comprobar funcionamiento
Una vez realizados todos estos pasos y solucionado algún error menor con algún namespace "peleón", la ventana de errores estaba vacía. Así que dando un doble salto mortal le dí al botón de generar aplicación web e inicié la aplicación en el navegador.
Lo primero que me di cuenta es que cada vez que se iniciaba la aplicación el portal me redirigía a la aplicación antigua. Después de leer algo y ver la configuración del DotNetNuke, me di cuenta de la utilidad de los alias en el portal -perdón a los expertos en DNN, ya comenté que no tengo experiencia en el portal :P
Para añadir un alias con la nueva URL a la WebApplication, existen dos formas que yo conozca:
- Añadiéndola a través del propio interfaz del portal, en herramientas de Host>Porltal>Aliases
- Añadiendo un registro en la base de datos en la tabla dbo.dnn_PortalAlias
Una vez añadido el registro, hay que hacer que la aplicación web se reinicie porque estos datos son cacheados durante el inicio de la aplicaicón. Para ello, basta por ejemplo escribir un espacio en el web.config y guardarlo.
NOTA: aparte del nuevo alias en la imagen se ven más, que corresponden a la publicación en Development Fabric y el sitio real en Azure. La captura la he hecho una vez que lo he publicado todo.
NOTA: aparte del nuevo alias en la imagen se ven más, que corresponden a la publicación en Development Fabric y el sitio real en Azure. La captura la he hecho una vez que lo he publicado todo.
Ya teníamos convertido el WebSite en una WebApplication
Conclusión
Convertir el sitio web en una aplicación web era un paso necesario para poder publicar un WebRole en Windows Azure. Aunque realmente en este paso no se ha hecho ninguna tarea de recodificación, era un paso necesario para llevar a cabo la migración.
Una vez realizados estos pasos, el siguiente era inminente: convertir la WebApplication en un WebRole y probarlo con el SDK en Development Fabric.
Hasta aquí el capítulo de hoy. En el próximo más.
Como siempre les dejo el enlace al portal que he publicado en Azure para que vayan viendo la evolución.
hola, esta muy interesante tu post, mi pregunta es, si ya instale el starter y quiero agrega un nuevo proyecto como le hago espero me ayudes gracias
ResponderEliminar