Introducción a los controladores HTTP

Un controlador HTTP de ASP.NET es el proceso que se ejecuta como respuesta a una solicitud realizada a una aplicación Web ASP.NET. El controlador más común es el de la página ASP.NET que procesa archivos .aspx. Cuando los usuarios solicitan un archivo .aspx, la página procesa la solicitud a través del controlador de la página.

El controlador de páginas de ASP.NET sólo es un tipo de controlador. ASP.NET viene con otros controladores integrados como el controlador del servicio Web para archivos .asmx.

Puede crear controladores HTTP personalizados cuando desee un control especial que puede identificar utilizando extensiones de nombre de archivo en su aplicación. Por ejemplo, los siguientes escenarios constituyen un buen uso de los controladores HTTP personalizados:

  • Suministros RSS   Para crear un suministro RSS para un sitio determinado, puede crear un controlador que emita XML con formato RSS. Puede enlazar a continuación la extensión .rss (por ejemplo) de su aplicación al controlador personalizado. Cuando los usuarios envían una solicitud al sitio que finaliza en .rss, ASP.NET llama al controlador para procesarla.

  • Servidor de imágenes   Si desea que su aplicación Web sirva imágenes en diferentes tamaños, puede

  •  escribir un controlador personalizado para cambiar el tamaño de las imágenes y después devolverlas al usuario como respuesta del controlador.

Los controladores HTTP tienen acceso al contexto de la aplicación, por ejemplo, a la identidad (si se conoce) del usuario que realiza la solicitud, al estado de la aplicación y a la información de la sesión. Cuando se necesita un controlador HTTP, ASP.NET llama al método ProcessRequest en el controlador adecuado. El método ProcessRequest del controlador crea una respuesta, que se devuelve al explorador que realizó la solicitud. Como con cualquier solicitud de página, la respuesta pasa por cualquier módulo HTTP que se ha suscrito a eventos que aparecen después de que el controlador se haya ejecutado.

Un controlador HTTP puede ser sincrónico o asincrónico. Un controlador sincrónico no vuelve hasta que termina de procesar la solicitud HTTP para la que se le llamó. Un controlador asincrónico ejecuta un proceso independientemente del envío de una respuesta al usuario. Los controladores asincrónicos son útiles cuando se necesita iniciar un proceso de aplicación que puede ser largo y el usuario no necesita esperar hasta que éste finalice antes de recibir una respuesta del servidor.

Controladores HTTP integrados en ASP.NET

ASP.NET asigna solicitudes HTTP a controladores HTTP en función de la extensión del nombre de un archivo. Cada controlador HTTP permite el procesamiento de direcciones URL HTTP individuales o grupos de extensiones URL dentro de una aplicación. ASP.NET incluye varios controladores HTTP integrados, como se muestra en la tabla siguiente.

Controlador

Descripción

Controlador de páginas ASP.NET (*.aspx)

Controlador HTTP predeterminado para todas las páginas ASP.NET.

Controlador de servicios Web (*.asmx)

Controlador HTTP predeterminado para las páginas de servicios Web creados con ASP.NET.

Controlador de controles de usuario ASP.NET (*.ascx)

Controlador HTTP predeterminado para todas las páginas de controles de usuario ASP.NET.

Controlador de seguimiento (trace.axd)

Controlador que muestra la información de seguimiento de la página actual.

Crear un controlador HTTP personalizado

Para crear un controlador HTTP personalizado, cree una clase que implemente la interfaz IHttpHandler para crear un controlador sincrónico o el IHttpAsyncHandler para crear un controlador asincrónico. Las dos interfaces del controlador requieren que implemente la propiedad IsReusable y el método ProcessRequest. La propiedad IsReusable especifica si el objeto IHttpHandlerFactory (el objeto que llama al controlador apropiado) puede colocar sus controladores en un grupo y reutilizarlos para mejorar el rendimiento, o si debe crea nuevas instancias cada vez que se necesite el controlador. El método ProcessRequest es responsable de procesar las solicitudes HTTP individuales.

Crear una extensión de nombre de archivo

Cuando crea un archivo de clase como su controlador HTTP, puede hacer que su controlador responda a cualquier extensión de nombre de archivo que aún no esté asignada en IIS y en ASP.NET. Por ejemplo, si está creando un controlador HTTP para generar un suministro RSS, puede asignar su controlador a la extensión .rss. Para que ASP.NET sepa el controlador que se debe utilizar para la extensión del nombre de archivo personalizado, la extensión del archivo de la clase del controlador debe asignarse en IIS a ASP.NET y en su aplicación al controlador personalizado.

De forma predeterminada, ASP.NET asigna la extensión del nombre de archivo .ashx a los controladores HTTP personalizados, de la misma manera que asigna la extensión .aspx al controlador de la página ASP.NET. Por consiguiente, si crea una clase de controlador HTTP con la extensión de nombre de archivo .ashx, el controlador se registra automáticamente con IIS y ASP.NET.

Si desea crear una extensión de nombre de archivo personalizado para su controlador, debe registrar de forma explícita la extensión con IIS y ASP.NET. La ventaja de no utilizar la extensión de nombre de archivo .ashx es que el controlador se puede volver a utilizar para diferentes asignaciones de extensiones. Por ejemplo, en una aplicación su controlador de cliente puede responder a solicitudes que terminen en .rss, y en otra aplicación a las solicitudes que terminen en .feed. Otro ejemplo podría ser que su controlador estuviera asignado a ambas extensiones de nombre de archivo en la misma aplicación, pero pueda crear respuestas diferentes basándose en la extensión

Controladores HTTP asincrónicos

Los controladores HTTP asincrónicos permiten iniciar un proceso externo, como por ejemplo una llamada a un método en un servidor remoto, y después continuar procesando sin esperar a que termine el proceso externo. Durante el procesamiento de un controlador HTTP asincrónico, ASP.NET coloca el subproceso que normalmente se utilizaría para el proceso externo de nuevo en el grupo de subprocesos hasta que el controlador reciba una devolución de llamada del proceso externo. Esto puede evitar el agrupamiento en bloques de los subprocesos y mejorar en gran manera el rendimiento ya que solo es posible ejecutar inmediatamente un número limitado de subprocesos. Si varios usuarios solicitan controladores HTTP sincrónicos que dependan de procesos externos, el sistema operativo puede quedarse sin subprocesos rápidamente porque muchos estarán bloqueados y esperando un proceso externo.

Cuando crea un controlador asincrónico, además de implementar la interfaz IHttpAsyncHandler, debe implementar BeginProcessRequest para iniciar una llamada asincrónica para procesar solicitudes individuales de HTTP. También debe implementar el método EndProcessRequest para ejecutar código de limpieza cuando el proceso finaliza.

Clases IHttpHandlerFactory personalizadas

La clase IHttpHandlerFactory recibe solicitudes y es responsable de reenviar una solicitud a un controlador HTTP adecuado. Puede crear un generador del controlador HTTP personalizado creando una clase que implementa la interfaz IHttpHandlerFactory. Crear un generador del controlador personalizado puede permitir el control más preciso del procesamiento de una solicitud HTTP creando controladores diferentes basados en condiciones en tiempo de ejecución. Por ejemplo, con un generador de controladores HTTP personalizado es posible crear una instancia de un controlador HTTP para un tipo de archivo si el método de solicitudes HTTP es PUT y otro distinto si el método es GET.

Crear controladores HTTP sincrónicos

En el ejemplo de código se muestra:

  1. El código para una clase de controlador HTTP. La clase debe implementar el método ProcessRequest y la propiedad IsReusable.

  2. Los elementos que se requieren en un archivo Web.config para registrar el controlador y asignarle la extensión de nombre de archivo .sample.

  3. En Servicios de Internet Information Server (IIS), cómo asignar la extensión de nombre de archivo .sample a ASP.NET

    Para crear la clase de controlador HTTP HelloWorldHandler

    public bool IsReusable

    {

    // To enable pooling, return true here.

    // This keeps the handler in memory

    get { return false; }

    }

    public void ProcessRequest(HttpContext context)

    {

    HttpRequest Request = context.Request;

    HttpResponse Response = context.Response;

    // This handler is called whenever a file ending

    // in .sample is requested. A file with that extension

    // does not need to exist.

    Response.Write(

    "<html>");

    Response.Write(

    "<body>");

    Response.Write("<h1>Hello from a synchronous custom HTTP handler.</h1>");

    Response.Write("</body>");

    Response.Write(

    "</html>");

    }

    El código implementa el método ProcessRequest y escribe una cadena en la propiedad Response del objeto HttpContext actual.

    Registrar un controlador HTTP personalizado

    Después de haber creado la clase de controlador HTTP personalizado, debe registrarlo en el archivo Web.config de la aplicación. Esto permite a ASP.NET buscar el controlador cuando recibe solicitudes realizadas a recursos cuya dirección URL finaliza en .sample.

    Para registrar un controlador HTTP personalizado en el archivo Web.config

    <configuration>
        <system.web>
            <httpHandlers>
                <add verb="*" path="*.sample"
                      type="HelloWorldHandler"/>
            </httpHandlers>
        </system.web>
    </configuration>

    El código registra el controlador personalizado por nombre de clase y le asigna la extensión de nombre de archivo .sample.

    Configurar IIS 6.0 para una extensión de controlador HTTP

    IIS sólo pasa las solicitudes para ciertos tipos de archivo a ASP.NET para darles servicio. De forma predeterminada, los archivos con extensiones de nombre de archivo como .aspx, .ascx y .asmx se asignan en IIS 6.0 a la extensión ISAPI de ASP.NET (Aspnet_isapi.dll). Sin embargo, si desea que ASP.NET controle las extensiones de dirección URL personalizadas, debe asignar las extensiones en IIS.

    Para asignar la extensión de nombre de archivo .sample a ASP.NET en IIS 6.0

  1. Abra el Administrador de Servicios de Internet Information Server (IIS).

  • Haga clic con el botón secundario en el nombre de la aplicación y, a continuación, haga clic en Propiedades.

  • Haga clic en la ficha Directorio virtual y, a continuación, en Configuración.

  • En la ficha Asignaciones, haga clic en Agregar.

  • En el cuadro Ejecutable, escriba Aspnet_isapi.dll o vaya a dicho archivo. De forma predeterminada, el archivo está en la ubicación siguiente

    %windows%\Microsoft.NET\Framework\version\

  • En el cuadro Extensión, escriba .sample

  • Desactive la casilla de verificación Comprobar si el archivo existe.

  • Haga clic en Aceptar y, a continuación, cierre el Administrador IIS.

    Probar el controlador HTTP personalizado

    Cuando haya creado y registrado el controlador HTTP personalizado, puede probarlo solicitando un recurso que tenga la extensión de nombre de archivo .sample.

    Para probar el controlador HTTP personalizado

    En el explorador, escriba una dirección URL que indique la aplicación Web y termine en .sample, como:

    http://localhost/SampleApplication/test.sample

    Crear un controlador HTTP asincrónico

    El ejemplo de código siguiente muestra un controlador HTTP asincrónico que procesa solicitudes para los archivos con la extensión de nombre de archivo .SampleAsync dentro de una aplicación ASP.NET. El ejemplo muestra el código para el controlador y después cómo asignar la extensión .SampleAsync al controlador en ASP.NET. Finalmente, el ejemplo muestra cómo asignar la extensión .SampleAsync a ASP.NET en IIS, de modo que IIS reenvíe las solicitudes que terminen en .SampleAsync a ASP.NET.

     crear la clase de controlador HTTP HelloWorldAsyncHandler

    class AsynchOperation : IAsyncResult
    {
        private bool _completed;
        private Object _state;
        private AsyncCallback _callback;
        private HttpContext _context;

        bool IAsyncResult.IsCompleted { get { return _completed; } }
        WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
        Object IAsyncResult.AsyncState { get { return _state; } }
        bool IAsyncResult.CompletedSynchronously { get { return false; } }

        public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
        {
            _callback = callback;
            _context = context;
            _state = state;
            _completed = false;
        }

        public void StartAsyncWork()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
        }

        private void StartAsyncTask(Object workItemState)
        {

            _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");

            _context.Response.Write("Hello World from Async Handler!");
            _completed = true;
            _callback(this);
        }
    }

    class AsynchOperation : IAsyncResult
    {
        private bool _completed;
        private Object _state;
        private AsyncCallback _callback;
        private HttpContext _context;

        bool IAsyncResult.IsCompleted { get { return _completed; } }
        WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
        Object IAsyncResult.AsyncState { get { return _state; } }
        bool IAsyncResult.CompletedSynchronously { get { return false; } }

        public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
        {
            _callback = callback;
            _context = context;
            _state = state;
            _completed = false;
        }

        public void StartAsyncWork()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
        }

        private void StartAsyncTask(Object workItemState)
        {

            _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");

            _context.Response.Write("Hello World from Async Handler!");
            _completed = true;
            _callback(this);
        }
    }

    El código implementa el método BeginProcessRequest. El método escribe una cadena en la propiedad Response del objeto actual HttpContext, crea una nueva instancia de la clase AsyncOperation y llama al método StartAsyncWork. El método StartAsyncWork agrega a continuación el delegado StartAsyncTask al objeto ThreadPool. Cuando un subproceso esté disponible, se llama al método StartAsyncTask, que escribe otra cadena en la propiedad Response y después la tarea finaliza al invocar al delegado AsyncCallback.

    Registrar el controlador HTTP personalizado

    Una vez creada la clase del controlador HTTP personalizado, se debe registrar en el archivo Web.config para que ASP.NET atienda las solicitudes de los archivos con la extensión .SampleAsync

    El código implementa el método BeginProcessRequest. El método escribe una cadena en la propiedad Response del objeto actual HttpContext, crea una nueva instancia de la clase AsyncOperation y llama al método StartAsyncWork. El método StartAsyncWork agrega a continuación el delegado StartAsyncTask al objeto ThreadPool. Cuando un subproceso esté disponible, se llama al método StartAsyncTask, que escribe otra cadena en la propiedad Response y después la tarea finaliza al invocar al delegado AsyncCallback.

    Una vez creada la clase del controlador HTTP personalizado, se debe registrar en el archivo Web.config para que ASP.NET atienda las solicitudes de los archivos con la extensión .SampleAsync.

    Para registrar el controlador HTTP personalizado en el archivo Web.config

    1. Si su sitio Web aún no tiene un archivo Web.config, cree uno.

    2. Agregue el código siguiente al archivo Web.config:

      <configuration>
        <system.web>
          <httpHandlers>
            <add verb="*" path="*.SampleAsync"
              type="HelloWorldAsyncHandler"/>
          </httpHandlers>
        </system.web>
      </configuration>

      El código registra el controlador HelloWorldAsyncHandler como el controlador para solicitudes que finalizan con .SampleAsync.

      Para asignar la extensión en IIS

      1. Abra el Administrador de servicios de Internet.

      2. Haga clic con el botón secundario del mouse (ratón) en la aplicación y elija Propiedades.

      3. En la ficha Directorio, haga clic en Configuración.

      4. Seleccione la ficha Asignaciones.

      5. Agregue una nueva asociación que asigne .SampleAsync a la versión de Aspnet_isapi.dll que desea utilizar.

      6. Si desea que el controlador se ejecute sin tener en cuenta la existencia o no de un archivo con el nombre que solicita el usuario, borre la casilla de verificación Comprobar si el archivo existe.

      Probar el controlador HTTP personalizado

      Una vez creado y registrado, puede probar el controlador HTTP personalizado solicitando un recurso con la extensión .SampleAsync de la aplicación.

      Para probar el controlador HTTP personalizado

      Crear generadores de controladores HTTP

      La interfaz IHttpHandlerFactory crea y administra controladores HTTP para procesar las solicitudes. Por tanto, es posible crear una clase que implemente la interfaz IHttpHandlerFactory y utilizar esa clase como controlador HTTP. Esto puede permitir un mayor control sobre el procesamiento de una solicitud HTTP, ya que se asigna una dirección URL a un generador de controladores HTTP que crea controladores diferentes en función de un complejo conjunto de condiciones. Por ejemplo, con un generador de controladores HTTP puede crear un número limitado de objetos controladores HTTP que tienen acceso a recursos costosos o limitados, como conexiones de base de datos, y reutilizar después esos objetos controladores en futuras solicitudes.

      En el ejemplo siguiente se utiliza un generador de controladores HTTP para crear dos controladores para recursos que se identifican con la extensión .sample: uno para una solicitud GET de HTTP y otro para una solicitud POST de HTTP. El primero es una instancia del controlador creado en Cómo: Crear controladores HTTP sincrónicos y el segundo es una instancia del controlador creado en Cómo: Crear un controlador HTTP asincrónico.

      Crear un generador de controladores HTTP personalizado

      Para crear una clase de generador de controladores HTTP HandlerFactory

      1. Cree una clase denominada HelloWorldHandler en el directorio App_Code de su sitio Web.

      Agregue el código siguiente al archivo de clase.

      class HandlerFactory : IHttpHandlerFactory
      {
          public IHttpHandler GetHandler(HttpContext context,
              string requestType, String url, String pathTranslated)
          {
              IHttpHandler handlerToReturn;
              if ("get" == context.Request.RequestType.ToLower())
              {
                  handlerToReturn = new HelloWorldHandler();
              }
              else if ("post" == context.Request.RequestType.ToLower())
              {
                  handlerToReturn = new HelloWorldAsyncHandler();
              }
              else
              {
                  handlerToReturn = null;
              }
              return handlerToReturn;
          }
          public void ReleaseHandler(IHttpHandler handler)
          {
          }
          public bool IsReusable
          {
              get
              {
                  return false;
              }
          }
      }

      El código implementa el método GetHandler de la interfaz IHttpHandlerFactory y devuelve el controlador sincrónico creado si la solicitud es una solicitud GET. Si la solicitud es una solicitud POST, devuelve la interfaz de controlador asincrónica.

      Crear controladores HTTP personalizados

      El generador de controladores HTTP personalizado devuelve el controlador sincrónico creado en Cómo: Crear controladores HTTP sincrónicos o el controlador asincrónico creado en Cómo: Crear un controlador HTTP asincrónico. Debe crear tanto la clase sincrónica HelloWorldHandler como la clase asincrónica HelloWorldAsyncHandler para que el generador de controladores HTTP personalizado pueda devolver esos controladores.

      Para crear las clases HelloWorldHandler y HelloWorldAsyncHandler

      1. Cree una clase denominada HelloWorldHandler en el directorio App_Code de su sitio Web.

      2. Agregue el código de Cómo: Crear controladores HTTP sincrónicos al archivo de clase.

      3. Cree una clase denominada HelloWorldAsyncHandler en el directorio App_Code de su sitio Web.

      4. Agregue el código de Cómo: Crear un controlador HTTP asincrónico al archivo de clase.

      • Vaya a su aplicación y escriba una dirección URL en el explorador que finaliza en .SampleAsync.


    Habilitar el seguimiento de una aplicación ASP.NET

    En lugar de habilitar el seguimiento para páginas individuales, puede habilitarlo para toda la aplicación. En ese caso, cada página de la aplicación muestra información de seguimiento. El seguimiento de la aplicación es útil cuando está desarrollando una aplicación porque puede habilitarlo y deshabilitarlo fácilmente sin editar páginas individuales. Cuando la aplicación está completa, puede deshabilitar el seguimiento para todas las páginas a la vez.

    Cuando se habilita el seguimiento para una aplicación, ASP.NET recopila la información de seguimiento de cada solicitud realizada a la aplicación, hasta llegar al número máximo de solicitudes especificado. El número predeterminado de solicitudes es 10

    De manera predeterminada, cuando el visor de seguimiento llega a su límite de solicitudes, la aplicación ya no almacena más solicitudes de seguimiento. No obstante, puede configurar el seguimiento de nivel de aplicación para almacenar siempre los datos de seguimiento más recientes y eliminar los datos más antiguos cuando se supera el número máximo de solicitudes

    La configuración en el archivo Web.config del sitio Web:

    <configuration>
      <system.web>
        <trace enabled="true" pageOutput="false" requestLimit="40" localOnly="false"/>
      </system.web>
    </configuration>

     

    About justindeveloper

    I am MCP (Microsoft Certified Professional). MCTS (Microsoft Certified Technology Specialist) and MCPD (Microsoft Certified Professional Developer), also I am SAP Business One Certified!! Desarrollando desde el IDE de Visual Studio NET 2003 hasta ahora con el Visual Studio NET 2010. Desde Microsoft SQL Server 2000 hasta ahora con el Microsoft SQL Server 2008 R2 y tambien con SharePoint, desde WSS 3.0 y MOSS 2007 y ahora familirizandome con el Sharepoint Foundation 2010 & Sharepoint Server 2010. The software development will follow being every time more wonderful!
    This entry was posted in Development. Bookmark the permalink.