Compartir a través de


Desarrollar módulos y controladores de IIS 7.0 con .NET Framework

por Mike Volodarsky

Información general

Este artículo se centra en empezar a desarrollar características de servidor web de IIS 7.0 y versiones posteriores basadas en .NET Framework. En este artículo se explica:

  1. Cómo decidir si se va a desarrollar un módulo IIS o un controlador de IIS
  2. Configuración del entorno de desarrollo, con Visual Studio, Visual C# Express o herramientas de línea de comandos proporcionadas con .NET Framework
  3. Cómo crear su primer proyecto
  4. Cómo desarrollar un módulo y un controlador sencillos
  5. Cómo implementar un módulo y un controlador sencillos en un servidor IIS

Para ver algunos módulos y controladores de IIS administrados del mundo real, y descargarlos para la aplicación, visite Solicitudes de redirección a la aplicación con el módulo HttpRedirection, Obtener listas de directorios bonitos para su sitio web de IIS con DirectoryListingModule y Mostrar iconos de archivos llamativos en sus aplicaciones de ASP.NET con IconHandler.

Introducción: desarrollar funciones de IIS con ASP.NET

Las versiones de IIS anteriores a IIS 7.0 incluían una API de C, denominada ISAPI, como UNA API de extensibilidad principal para crear características de servidor web. IIS 7.0 y versiones posteriores se han rediseñado desde cero para proporcionar una nueva API de C++, en la que se basan todas las características integradas, para permitir una extensibilidad completa del entorno de ejecución del servidor web.

Además de esto, IIS por primera vez también proporciona una API de .NET de plena fidelidad para ampliar el servidor web, aprovechando una estrecha integración con ASP.NET 2.0. Para usted, esto significa que ahora puede ampliar IIS con nuevas características de servidor web creadas con las API de ASP.NET 2.0 conocidas. Del mismo modo, puede usar módulos y controladores de ASP.NET 2.0 existentes en IIS, aprovechando ASP.NET integración para mejorar la eficacia de la aplicación sin escribir ningún código nuevo. Para obtener más información sobre la integración de ASP.NET en IIS, consulte Integración de ASP.NET con IIS 7.

Herramientas del comercio: decidir sobre su entorno de desarrollo

Para compilar módulos y controladores de IIS, use cualquier entorno que le permita desarrollar y compilar ensamblados de .NET. Las opciones más comunes son:

  1. Visual Studio 2005 También puede descargar la versión beta más reciente de Visual Studio 2008.
  2. Visual C# 2005 Express Edition, una descarga gratuita (u otras herramientas de Express, como Visual Basic 2005 Express).
  3. El compilador de línea de comandos de C# (csc.exe) incluido en el entorno de ejecución de .NET Framework (para otros lenguajes, deberá descargar el SDK), además del editor de origen favorito.

Los ejemplos de este artículo usan C#, aunque puede desarrollar componentes de IIS en cualquier otro lenguaje .NET compatible (excepto C++administrado). En el artículo se muestra cómo desarrollar componentes de extensibilidad de IIS con los tres entornos anteriores.

Nota:

Dado que IIS aprovecha las API de ASP.NET existentes para su extensibilidad de .NET, puede desarrollar módulos y controladores de .NET de IIS con .NET Framework 2.0 en Windows XP® y Windows Server® 2003. Sin embargo, si tiene previsto usar una de las varias API de ASP.NET nuevas que se han agregado para admitir nuevas características de IIS, debe desarrollar en Windows Vista® o obtener la versión de System.Web.dll de en Windows Vista o la versión más reciente de .NET Framework 3.5 para compilar el código.

Dos maneras de extender IIS: Módulo vs. Controlador

Todas las características del servidor web de IIS caben en dos categorías: módulos y controladores.

Un módulo, similar al filtro ISAPI en versiones anteriores de IIS, participa en el procesamiento de solicitudes de cada solicitud para cambiarla o agregarla de alguna manera. Algunos ejemplos de algunos módulos en IIS incluyen módulos de autenticación, que manipulan el estado de autenticación de la solicitud, los módulos de compresión que comprimen la respuesta saliente y registran los módulos que registran información sobre la solicitud a los registros de solicitudes.

El módulo es una clase .NET que implementa la interfaz System.Web.IHttpModule de ASP.NET y usa las API del espacio de nombres System.Web para participar en uno o varias de las fases de procesamiento de solicitudes de ASP.NET.

Un controlador, similar a la extensión ISAPI en versiones anteriores de IIS, es responsable de controlar la solicitud y generar la respuesta para tipos de contenido específicos. La principal diferencia entre el módulo y el controlador es que el controlador se asigna normalmente a una ruta de acceso o extensión de solicitud determinada, y admite el procesamiento de un recurso de servidor específico al que corresponde esa ruta de acceso o extensión. Entre los ejemplos de controladores proporcionados con IIS se incluyen ASP, que procesa scripts ASP, el controlador de archivos estáticos, que sirve archivos estáticos y ASP. PageHandler de NET que procesa páginas ASPX.

El controlador es una clase .NET que implementa el ASP.NET System.Web.IHttpHandler o la interfaz System.Web.IHttpAsyncHandler y usa las API del espacio de nombres System.Web para generar una respuesta HTTP para contenido específico que admita.

Al planear el desarrollo de una característica de IIS, la primera pregunta que debe formular es si esta característica es responsable de atender solicitudes a una dirección URL o extensión específica, o se aplica a todas o algunas solicitudes basadas en reglas arbitrarias. En el primer caso, debe ser un controlador y, en este último, un módulo.

En este artículo se muestra cómo crear un módulo sencillo y un controlador sencillo, los pasos comunes para crear el proyecto y compilarlo y los pasos específicos para implementarlos en el servidor.

Nota:

No es necesario desarrollar un controlador si está desarrollando un módulo y visa-versa.

Introducción: crear un proyecto de Visual Studio

Para compilar un módulo o un controlador, debe generar un ensamblado de .NET (DLL) que contenga las clases module/handler. Si usa las herramientas de Visual Studio o Visual Studio Express, el primer paso consiste en crear un proyecto de biblioteca de clases:

  1. En el menú "Archivo", seleccione "Nuevo", "Proyecto ...". En el cuadro de diálogo Nuevo proyecto (siguiente), seleccione el tipo de proyecto "Visual C#" y seleccione la "Biblioteca de clases" en la lista derecha de plantillas instaladas de Visual Studio.

    Create an IIS7 module and handler project in Visual Studio

  2. Debemos agregar una referencia al ensamblado "System.Web.dll", que contiene las API que se usan para desarrollar ASP.NET y módulos y controladores de IIS. Haga clic con el botón derecho en el nodo "Referencias" en el nodo Proyecto en la vista de árbol del Explorador de soluciones de la derecha, elija "Agregar referencia ..." y, en la pestaña .NET, seleccione el ensamblado System.Web, versión 2.0 (a continuación).

    Add reference to System.Web.dll

Nota:

Puede usar la versión 2.0 del ensamblado System.Web en Windows XP y Windows Server 2003 si no tiene previsto aprovechar las API específicas de IIS ASP.NET. Los módulos y controladores compilados que hacen referencia a este ensamblado se pueden implementar y operar en IIS en Windows Vista y Windows Server 2008 sin ningún problema. Si desea usar las pocas API de ASP.NET específicas de IIS en el módulo, debe desarrollar en Windows Vista, Windows Server 2008 o obtener el ensamblado System.Web.dll de .NET Framework 3.5. Las API específicas de IIS incluyen HttpServerUtility.TransferRequest, la colección HttpResponse.Headers, el evento HttpApplication.LogRequest y otros.

Escritura de código: creación de un módulo simple

La primera tarea consiste en crear un módulo sencillo. Más adelante en el artículo, también creamos un controlador de ejemplo.

Para crear un módulo, defina una clase que implemente la interfaz System.Web.IHttpModule.

  1. Elimine el archivo "class1.cs" generado por el sistema de proyecto y agregue una nueva clase de C# llamada MyModule haciendo clic con el botón derecho en el proyecto MyIIS7Project en la vista de árbol derecho, seleccionando "Agregar", Nuevo elemento", seleccionando "Clase" y escribiendo "MyModule.cs" en el campo Nombre.

  2. Importe el espacio de nombres System.Web para que podamos acceder fácilmente a los tipos que contiene.

  3. Haga que nuestra clase MyModule implemente la interfaz IHttpModule y defina los miembros de interfaz Dispose() e Init(). Para ello, haga clic con el botón derecho en la interfaz IHttpModule y elija la opción "Implementar interfaz":

    A simple IHttpModule class in Visual Studio

    El método Dispose() está diseñado para limpiar los recursos no administrados de forma determinista cuando se descarga el módulo, por lo que los recursos se pueden liberar antes de que el recolector de elementos no utilizados finalice la instancia del módulo. Puede dejar este método en blanco la mayor parte del tiempo.

    El método Init(contexto HttpApplication ) es el método principal de interés. Su rol es realizar la inicialización del módulo y conectar el módulo a uno o varios eventos de procesamiento de solicitudes disponibles en la clase HttpApplication. Durante el procesamiento de solicitudes, se invocará el módulo para cada uno de los eventos a los que se suscribió, lo que le permitirá ejecutar y realizar su servicio. Para ello:

  4. Suscríbase a uno o varios de los eventos de procesamiento de solicitudes mediante el cableado de un método en la clase de módulo a uno de los eventos de la instancia de HttpApplication proporcionada. El método debe seguir la firma del delegado System.EventHandler. Definimos un nuevo método, llamado OnPreExecuteRequestHandler, y lo conectamos al evento HttpApplication.PreRequestRequestHandlerExecute, que se produce justo antes de que el servidor vaya a invocar el controlador de la solicitud para la solicitud:

    public void Init(HttpApplication context) 
    { 
        context.PreRequestHandlerExecute += 
            newEventHandler(OnPreRequestHandlerExecute) 
    }
    

    Implement IHttpModule.Init() in Visual Studio

    En este momento, nuestro módulo está configurado para recibir el evento PreRequestHandlerExecute en cada solicitud. Puede repetirlo para todos los demás eventos que le gustaría recibir.

  5. Ahora hacemos que nuestros módulos hagan algo útil, algo que ilustra el uso de algunas de las API de ASP.NET que un módulo podría usar. Compruebe si la solicitud especifica un encabezado de referencia y, si lo hace, lo rechaza, como una forma tonta para evitar que las personas vinculen a su sitio web desde otros sitios web. Lo haremos en nuestro método OnPreRequestHandlerExecute que se invoca justo antes de que el controlador se ejecute en cada solicitud:

    public void OnPreRequestHandlerExecute (
       Object source, EventArgs e) 
    { 
       HttpApplication app = (HttpApplication)source; 
       HttpRequest    request = app.Context.Request; 
    
       if (!String.IsNullOrEmpty( request.Headers["Referer"] )) 
       { 
           throw new HttpException(403, 
                                                   "Uh-uh!"); 
       } 
    }
    

    Implement IHttpModule

    Nota:

    La instancia de HttpApplication se proporciona al módulo a través del argumento source y requiere la conversión. Puede acceder al resto del modelo de objetos de solicitud desde la instancia de HttpApplication, como el objeto HttpContext y el objeto HttpRequest contenido que representa la solicitud.

El código anterior comprueba si se ha especificado el encabezado De referencia y, si es así, rechaza la solicitud con un código de error 403 No autorizado.

Escritura de código: crear un módulo simple

La siguiente tarea consiste en crear un controlador simple. Anteriormente en el artículo, creamos un módulo de ejemplo: vuelva si desea leer sobre la creación de un módulo en su lugar.

Para crear un controlador, debemos definir una clase que implemente la interfaz System.Web.IHttpHandler (también podemos implementar System.Web.IHttpAsyncHandler si queremos que la página se ejecute de forma asincrónica). Para ello:

  1. Si aún no lo ha hecho, elimine el archivo "class1.cs" generado por el sistema de proyecto y agregue una nueva clase de C# denominada MyHandler haciendo clic con el botón derecho en el proyecto MyIIS7Project en la vista de árbol derecho, seleccionando "Agregar", Nuevo elemento", seleccionando "Clase", y escriba "MyHandler.cs" en el campo Nombre.

  2. Importe el espacio de nombres System.Web para que podamos acceder fácilmente a los tipos que contiene.

  3. Haga que nuestra clase MyHandler implemente la interfaz IHttpHandler y defina los miembros de interfaz IsReusable y ProcessRequest(). Para ello, haga clic con el botón derecho en la interfaz IHttpHandler y elija la opción "Implementar interfaz":

    Implement the IHttpHandler interface in Visual Studio

    IsReusable () indica si la instancia del controlador se puede volver a usar para las solicitudes posteriores. En algunos casos, después de procesar la solicitud, el controlador puede estar en un estado incorrecto para procesar otra solicitud, especialmente si ha almacenado datos sobre la solicitud anterior en variables miembro. Tenga en cuenta que el tiempo de ejecución nunca usará la misma instancia del controlador para procesar dos solicitudes al mismo tiempo, incluso si se marca como reutilizable. Si el controlador no almacena ningún estado por solicitud en variables miembro y puede tener su función ProcessRequest llamada tantas veces como sea necesario, haga que esta propiedad devuelva true para permitir la reutilización.

    El método ProcessRequest () es el punto de entrada principal del controlador. Su rol consiste en procesar la solicitud especificada por la instancia de HttpRequest disponible en la instancia de HttpContext proporcionada y generar la respuesta adecuada mediante la instancia HttpResponse también disponible en HttpContext. El tiempo de ejecución invocará el método ProcessRequest() durante la fase de procesamiento de solicitudes ExecuteRequestHandler y SOLO SI la solicitud asignada al controlador se basa en las asignaciones de controladores configuradas. Esto es diferente de un módulo que recibe notificaciones para todas las solicitudes a la aplicación.

  4. Implemente primero la propiedad IsReusable. Dado que nuestro controlador no almacenará ningún estado miembro para la solicitud y podrá admitir varias llamadas a ProcessRequest() con solicitudes diferentes, la marcaremos como reutilizable devolviendo true.

    public bool IsReusable
    {
        get { return true; }
    
  5. Por último, vamos a implementar el método ProcessRequest() para que nuestro controlador haga realmente algo útil. Para mantener las cosas bien y sencillas, nuestro controlador devolverá la hora actual en el servidor, lo que opcionalmente permite especificar la zona horaria en la cadena de consulta. Nuestro objetivo es poder solicitar una dirección URL, como http://myserver/time.tm, y obtener la hora actual en el servidor. Además, podremos solicitar el tiempo coordinado universal mediante la solicitud de http://myserver/time.tm?utc=true. Aquí nuestra implementación:

    public void ProcessRequest(HttpContext context) 
    { 
        DateTime dt; 
        String useUtc = context.Request.QueryString["utc"]; 
        if (!String.IsNullOrEmpty(useUtc) && 
                useUtc.Equals("true")) 
        { 
            dt = DateTime.UtcNow; 
        } 
        else 
        { 
            dt = DateTime.Now; 
        } 
        context.Response.Write( 
            String.Format( "<h1>{0}</h1>", 
                           dt.ToLongTimeString() 
                           ) ); 
    }
    

    Usamos la colección HttpRequest.QueryString para recuperar una variable QueryString y escribir la hora actual para responder mediante el método HttpResponse.Write. Este es solo un ejemplo de los tipos de cosas que puede elegir hacer en el controlador: la clase HttpRequest proporciona mucha más información sobre la solicitud y la clase HttpResponse proporciona una serie de maneras diferentes para dar forma a la respuesta devuelta al cliente.

    Implement IHttpHandler.ProcessRequest in Visual Studio

El controlador se ha completado.

Código completado: compilar el módulo/controlador

Ahora que tenemos implementado el módulo y el controlador, podemos compilarlos en un ensamblado que ASP.NET se puede cargar en tiempo de ejecución. Si usa Visual Studio o Visual Studio Express, compile el proyecto directamente desde la herramienta presionando "Ctrl-Mayús-B" o haciendo clic con el botón derecho en el proyecto y seleccionando "Compilar".

El ensamblado .DLL se generará en la carpeta <ProjectDirectory>\bin\debug, junto con . Archivo de símbolos PDB que puede usar para depurar el ensamblado en el servidor o incluir líneas de código fuente en excepciones durante la fase de depuración del proyecto.

Si va a cargar el ensamblado en un servidor de producción, asegúrese de cambiar la configuración de la solución para que sea "Release" haciendo clic con el botón derecho en el nodo de la solución, seleccionando Configuration Manager y cambiando el tipo a Depurar. Cargue la versión release del ensamblado (deje atrás el archivo PDB): esto quitará la información de depuración del ensamblado y la optimizará, lo que dará lugar a código más rápido.

Si no usa Visual Studio, compile el proyecto con el compilador de línea de comandos de C# incluido en el entorno de ejecución de Framework. Para compilar el proyecto, abra un símbolo de la línea de comandos (asegúrese de ejecutar el símbolo de la línea de comandos con la opción "Ejecutar como Administración istrator" si está en Windows Vista o Windows Server 2008):

> %windir%\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /out:MyIIS7Project.dll /debug \*.cs /r:System.Web.dll

Esto genera los archivos MyIIS7Project.DLL y MyIIS7Project.PDB. Si desea compilar una versión de lanzamiento del ensamblado, omita el modificador /debug e incluya el modificador /o para optimizar el ensamblado.

Implementar el ensamblado en el servidor

Ahora que hemos implementado el módulo y el controlador personalizados, los implementamos en nuestra aplicación web. Hay varias maneras de implementar un módulo o controlador en la aplicación y varias opciones de configuración que puede usar para adaptar su implementación a sus necesidades. A continuación se muestran los pasos de implementación más básicos. Para obtener una explicación avanzada de las opciones de implementación y configuración, incluido cómo implementar un módulo o controlador para todo el servidor, consulte el siguiente artículo de la serie: Implementar módulos y controladores de IIS (próximamente).

En los pasos siguientes se supone que va a implementar el módulo y el controlador en una aplicación existente en el servidor IIS. Si no tiene una aplicación creada, use la aplicación raíz del "Sitio web predeterminado" que normalmente se encuentra en %systemdrive%\inetpub\wwwroot. En el ejemplo siguiente, implementamos el módulo y el controlador en una aplicación denominada "myiis7project" ubicada en el sitio web predeterminado.

Para implementar el módulo y el controlador, primero haga que el ensamblado que contiene su implementación esté disponible para la aplicación de ASP.NET:

  1. Copie el ensamblado MyIIS7Project.dll compilado anteriormente en el directorio /BIN ubicado en la raíz de la aplicación. Si este directorio no existe, créelo.

  2. Configure el módulo y el controlador que se van a cargar en la aplicación. Abra la herramienta de Administración de IIS7 a través del menú Inicio, escriba inetmgr.exe en el cuadro de inicio o búsqueda y presione Entrar. En la herramienta, haga doble clic en el nodo del servidor en la vista de árbol izquierdo, expanda el nodo "Sitios" y haga doble clic en el sitio o la aplicación a los que desea agregar el módulo y el controlador.

  3. Seleccione el icono de característica "Módulos", haga clic en la acción "Agregar módulo administrado ..." y, en el cuadro de diálogo resultante, escriba el nombre del módulo (arbitrario) y el tipo de módulo completo "MyIIS7Modules.MyModule". Tenga en cuenta que también puede seleccionar el tipo en el cuadro desplegable, ya que la herramienta cargará automáticamente el ensamblado en bin y detectará tipos que implementen la interfaz IHttpModule. Presione Aceptar para agregar el módulo.

    Adding an IIS7 module

  4. Agregue el controlador haciendo doble clic en el nodo de sitio o aplicación de nuevo y seleccionando el icono de característica "Mapeados de controlador". A continuación, haga clic en la acción "Agregar controlador administrado" y, en el cuadro de diálogo resultante, especifique "time.tm" para la ruta, "MyIIS7Modules.MyHandler" para el tipo y "MyHandler" para el nombre (arbitrario). De nuevo, tenga en cuenta que el tipo está presente en el cuadro desplegable porque la herramienta Administración detectó automáticamente este tipo en el ensamblado. Pulse Aceptar para agregar el controlador.

    Adding an IIS7 handler

La configuración de la aplicación generada por las acciones anteriores configura el módulo MyModule que se va a cargar en la aplicación (lo que permite que se ejecute para todas las solicitudes) y asigna el controlador MyHandler para procesar las solicitudes a la dirección URL de time.tm dentro de la aplicación.

Tenga en cuenta que esta configuración permite que el módulo y la aplicación solo se ejecuten en aplicaciones en modo integrado de IIS. Si desea que el módulo y el controlador también se ejecuten en aplicaciones en modo clásico en IIS y también en versiones anteriores de IIS, también debe agregar la configuración de la ASP.NET clásica para el módulo y el controlador. Además, cuando se ejecuta en modo clásico en IIS o en versiones anteriores de IIS, el controlador requiere que cree una asignación de mapa de script asignación de la extensión .tm a ASP.NET en mapas de scripts de IIS y el módulo solo se ejecuta para las solicitudes a extensiones asignadas a ASP.NET. Para obtener más información sobre esto, consulte Implementar módulos y controladores de IIS (próximamente).

También puede agregar el módulo y el controlador mediante la herramienta de línea de comandos de IIS, AppCmd.exe o manipulando la configuración de IIS desde el script o el código administrado, o colocando la configuración directamente en el archivo web.config. Estas opciones adicionales se describen en profundidad en Implementar módulos y controladores de IIS (próximamente).

Probar el módulo y el controlador

Hemos implementado y configurado el módulo/controlador. Ahora para probarlos:

  1. Pruebe nuestro controlador realizando una solicitud a "time.tm" en nuestra aplicación. Si se ejecuta correctamente, vemos la hora actual en el servidor. Realice una solicitud a la aplicación, por ejemplo http://localhost/myiis7project/time.tm, ya que hemos implementado el controlador en la aplicación myiis7project en el sitio web predeterminado:

    Si el controlador se implementa correctamente en esta aplicación, verá la hora actual en el servidor:

    Testing the IIS7 handler

    Intente también solicitar http://localhost/myiis7project/time.tm?utc=true que muestre la hora en UTC.

  2. Probar el módulo Cree una página html simple llamada page.html en su aplicación que se vincule a la URL /time.tm:

    page.html

    <html>
      <body>
          <a href="time.tm">View current server time</a>
      </body>
    </html>
    

    A continuación, realice una solicitud a http://localhost/myiis7project/page.html para mostrar el vínculo. Al hacer clic en el vínculo, observará un error:

    Testing the IIS7 module

    Puede preguntar si no solo solicitamos esta misma dirección URL anterior y ver correctamente la hora. Esto se debe a que nuestro módulo está configurado para rechazar solicitudes a su aplicación que especifiquen un encabezado Referrer, que es añadida por el navegador cada vez que un usuario hace clic en un enlace para ir a su sitio web en lugar de simplemente escribir la URL en el explorador directamente. Por lo tanto, cuando solicitó la dirección URL de forma directa, pudo acceder a ella; sin embargo, cuando siguió un vínculo desde otra página, nuestro módulo rechazó la solicitud.

Resumen

En este artículo, se ilustran los pasos básicos para desarrollar un módulo y un controlador de IIS con las API de ASP.NET conocidas e implementarlos en la aplicación. También hemos analizado las opciones que tiene para el entorno de desarrollo y cómo decidir cuándo crear un módulo frente a un controlador. La información de este artículo debería permitirle crear sus primeros módulos y controladores para potenciar sus aplicaciones IIS.

También puede revisar un módulo de ejemplo que habilita la autenticación básica contra los proveedores de pertenencia de ASP.NET en Desarrollar un módulo usando .NET.

Asegúrese de consultar más ejemplos de cómo los módulos y controladores de IIS administrados pueden agregar valor a las aplicaciones y descargarlos para su aplicación visitando Solicitudes de redirección a la aplicación con el módulo HttpRedirection, Obtener listas de directorios bonitas para su sitio web de IIS con DirectoryListingModule y Mostrar iconos de archivo llamativos en las aplicaciones de ASP.NET con IconHandler.