Windows Azure y Classic Pipeline

Por defecto, Windows Azure únicamente puede ejecutar aplicaciones web sobre IIS7.5, o por decirlo de otra manera, aplicaciones que utilizan el pipeline de IIS en modo integrado.

Aunque mi recomendación personal es actualizar la aplicación para poder ejecutarla utilizando el modo integrado, este post propone una alternativa para poder ejecutar una aplicación que necesite el pipeline en modo clásico, aunque sea como solución a corto plazo. Una buena referencia sobre como migrar aplicaciones de IIS 6.0 a IIS 7.0 está disponible aquí.

Para poder ejecutar una aplicación web diseñada para IIS 6.0 en un IIS 7.0 ó 7.5 simplemente tenemos que asegurarnos de que el Application Pool que utiliza esté configurado con un pipeline en modo clásico. Un equipo con Windows 7 o Windows 2008 R2 y con el .NET Framework 4.0 instalado tendrá los siguientes application pools por defecto:

image

El error “Request is not available in this context” es uno de los más comunes que se reciben si una aplicación web desarrollada para utilizar el pipeline en modo clásico se ejecuta en modo integrado:

image

Como hemos dicho, para que una aplicación web pueda ejecutarse con un pipeline en modo clásico sólo tenemos que modificar su application pool:

image

Bien, el problema que se nos presenta en Windows Azure es que, si queremos que nuestro cambio sea persistente y coherente con el modelo de Azure,  no podemos modificar la configuración manualmente ya que en el caso de que nuestro servidor(es) se regenerara, perderíamos dicha configuración.

La única alternativa que tenemos es utilizar la infraestructura software de Windows Azure, concretamente la clase RoleEntryPoint. Para ello, añadimos una clase en nuestra aplicación web que herede de RoleEntryPoint, después sobre-escribiremos el método “OnStart()” con el siguiente código (esta vez Visual Basic .NET):

 Public Overrides Function OnStart() As Boolean
     Dim srvManager As New ServerManager()
  
     Try
         Dim appSite = (From site In srvManager.Sites
                       Where site.Name.Contains(RoleEnvironment.CurrentRoleInstance.Role.Name)).FirstOrDefault()
         If Not appSite Is Nothing Then
             Dim appPool = (From pool In srvManager.ApplicationPools
                       Where pool.Name = appSite.Applications(0).ApplicationPoolName).FirstOrDefault()
             If (Not appPool Is Nothing) Then
  
                 appPool.ManagedPipelineMode = ManagedPipelineMode.Classic
  
                 srvManager.CommitChanges()
  
             End If
         Else
             Trace.WriteLine("Unable to get AppSite reference")
         End If
  
     Catch ex As Exception
         Trace.WriteLine("Exception: " + ex.ToString())
     Finally
         srvManager.Dispose()
     End Try
 End Sub
  
   

Este código depende de la librería Microsoft.Web.Administration por lo que tendrás que añadir la referencia en el proyecto.

La siguiente vez que ejecutemos la aplicación en un contexto Azure (tanto en el emulador como en un entorno Windows Azure real), el pipeline se configurará automáticamente para utilizar el modo clásico. Si el Web Role se regenera, no hay problema, el método “OnStart()” será invocado de nuevo.

Por último decir que este método sólo es válido si la aplicación utiliza .NET Framework 2.0/3.5. Para poder ejecutar una aplicación .NET Framework 4.0 en modo clásico hay que pasar por algún que otro inconveniente más y añadir más configuración (lo sé, no es algo que tenga mucho sentido, lo mejor sería actualizarla, pero hay de todo en la viña del Señor)… pero eso lo veremos en el siguiente post!