Development

Introducción a Windows Communication Foundation (antes conocida como Indigo)

Windows Communication Foundation es la nueva plataforma de Microsoft para crear aplicaciones distribuidas. Podríamos definirlo también como el modelo de programación unificado para crear aplicaciones distribuidas. Se lanzó al mercado como parte de .NET Framework 3.0 con la idea de consolidar y ampliar las API de versiones anteriores de Framework (por ejemplo, los servicios web ASP.NET, .NET Remoting, Enterprise Services (COM+) y Message Queuing).

 

Una de sus principales características es que cuenta con un modelo de programación unificado. Es la unificación de numerosas capacidades que antes podíamos encontrar en distintas tecnologías. Esto nos libra de tener que estar utilizando más de una tecnología para cumplir satisfactoriamente los requerimientos. De este modo, los desarrolladores harán una tarea de una única manera.

 

Las comunicaciones se enriquecen notablemente, ya que Windows Communication Foundation da la libertad al desarrollador de utilizar múltiples transportes, distintos tipos de formatos de mensajes y diversos patrones de mensajes.

 

La interoperabilidad es el plato fuerte de Windows Communication Foundation, ya que la comunicación es totalmente independiente de la plataforma. Los servicios utilizados son sobres de SOAP, cuyo contenido es nada menos que XML. Windows Communication Foundation está basado en la arquitectura de Web Services y utiliza los estándares establecidos.

 

El transporte es otra de sus cualidades fuertes, ya que éste se define con un protocolo neutral, de transporte neutral y formato neutral. Esto quiere decir que los servicios pueden utilizar tanto HTTP como TCP u otro mecanismo de transporte. Los desarrolladores tienen la posibilidad de agregar nuevos proveedores de transporte, y esto es indiferente al servicio. Windows Communication Foundation separa el “código” del “transporte”, y de esta manera soporta distintos métodos de comunicación, sin representar esto una carga de trabajo extra para el desarrollador.

 

 Teniendo una idea de lo que es WCF, abordaremos aspectos como las clases de servicio, los hosts de servicios, la configuración de servicios y los proxy de cliente.

 

Para empezar, cree una solución vacía denominada GettingStartedWithWCF.

 

wcf_intro_01

Clases de servicio

La clase de servicio implementa la funcionalidad que exponen las operaciones del servicio. Se trata de una clase .NET normal sin restricciones de herencia. Para habilitar una clase como clase del servicio, se aplican los atributos ServiceContract y OperationContract del espacio de nombres System.ServiceModel. Estos atributos pueden incluirse en la misma declaración de clase o simplemente en la declaración de una interfaz implementada por la clase. El uso de estos atributos no significa que la clase sea un servicio. Significa simplemente que la clase puede estar expuesta igual que un servicio.

Agregaremos un proyecto de biblioteca de clases para las clases de servicio. Para ello, haga clic con el botón secundario en la solución, seleccione Add | New Project y, a continuación, cree un proyecto de biblioteca de clases denominado ServiceLib.

wcf_intro_02

 

Cambie el nombre del archivo Class1.cs por MathService.cs

Agregue una referencia a System.ServiceModel.  Acabará usando este proyecto de manera habitual, ya que este ensamblado constituye la base de WCF.

Agregue dos métodos a la clase MathService: uno que agregue dos enteros (denominado Add) y uno que permita obtener el cuadrado de un doble (denominado Square). Agregue una instrucción Using al espacio de nombres System.ServiceModel y, a continuación, incluya en esta clase el atributo ServiceContract y en los métodos el atributo OperationContract.

using System.ServiceModel;

 

[ServiceContract]

public class MathService

{

    [OperationContract]

    public int Add(int x, int y)       

    {

        return x + y;

    }

    [OperationContract]

    public double square(double x)

    {

        return x * x;

    }

}

Como se ha mencionado anteriormente, estos atributos también pueden aplicarse a una interfaz. Para verlo, agregue una clase nueva al proyecto ServiceLib denominada HelloService y agregue el código que se muestra a continuación. 

using System.ServiceModel;

 

[ServiceContract]

public interface IHello

{

   [OperationContract]

   string SayHello(string name);

}

public class HelloService: IHello

{

    #region IHello Members

 

    public string SayHello(string name)

    {

        return "Hello " + name;

    }

 

    #endregion

}

Hosts de servicios

 

Para que la funcionalidad contenida en la clase del servicio esté a disposición de las aplicaciones cliente, se necesita un host de servicio. Se trata de una aplicación que escuchará las solicitudes de los clientes y creará instancias de la clase del servicio con el fin de procesar estas solicitudes. Con WCF, es posible usar IIS como host, pero también puede crearse una aplicación personalizada.

En este caso crearemos ambas clases de hosts, empezando por el hospedaje web. Haga clic con el botón secundario en la solución para agregar un sitio web. A continuación, seleccione Agregar | Nuevo sitio Web y elija la plantilla de servicio de WCF. Asegúrese de establecer la ubicación en una ruta de acceso del sistema de archivos en una carpeta del archivo de la solución

  wcf_intro_03

Veamos rápidamente el código del texto reutilizable de IService1.cs. La plantilla asume que vamos a codificar la funcionalidad para el servicio aquí, de modo que dispone de una interfaz y una clase de servicio de muestra con los atributos adecuados (además de un atributo DataContract).

Data Contract:

El Data Contract describe la estructura de datos que es manejada por las funciones del servicio.

También, con el Data Contract es posible especificar la estructura del tipo de datos que intercambia el servicio.

Permite, a la vez, convertir la estructura definida anteriormente en un XML Schema, el cual es un esqueleto de tipo datos y es un formato independiente de la plataforma utilizada.

Por último, define cómo se tienen que serializar y deserializar los nuevos datos.

Observación: en el caso de los tipos de datos simples (como un Integer, String, Boolean…), no es necesario crear un Contrato de Datos, ya que la conversión la realiza de manera automática. Sólo cuando se crean tipos de datos nuevos (como un objeto) se debe especificar el contrato de datos para su posible intercambio.

Ya hemos creado las clases de servicio en el proyecto de ServiceLib y, por lo tanto, ahora podemos eliminar el archivo Servicio.cs

Abra Service.svc y consulte los valores de los atributos. Los servicios de hospedaje web usan el mismo modelo que las antiguas tecnologías ASP.NET. Vinculan el archivo al que se pretende llegar con el archivo que contiene el código. Ésta es la misma técnica de código subyacente que se usa en ASP.NET.

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>

Dado que ya tenemos una clase de servicio compilada, podemos quitar este atributo y, a continuación, poner el nombre completo del tipo MathService como el valor para el atributo Service

 

<%@ ServiceHost Language="C#" Debug="true" Service="ServiceLib.MathService"%>

Finalmente, agregue una referencia al proyecto ServiceLib.

Esto es todo en cuanto al servicio de hospedaje web. Ahora seguiremos con el uso de aplicaciones personalizadas como hosts. Para ello, se puede usar una aplicación de Windows Forms, una aplicación de consola o bien un servicio de Windows. En este caso usaremos una aplicación de consola.

Haga clic con el botón secundario en la solución y elija Add | New Project. Cree una aplicación de consola denominada ConsoleServiceHost.

wcf_intro_04

Dado que necesitaremos crear referencias a System.ServiceModel (para la clase que realizará el hospedaje) y ServiceLib. (para la clase de servicio), primero agregue estas referencias.

Hacer que una aplicación .NET hospede un servicio es algo muy sencillo. Cree simplemente una instancia de tipo ServiceHost, asígnele el Type correspondiente a la clase de servicio que va a hospedar y, a continuación, llame el método Open. Este método Open hace que el host comience a escuchar las solicitudes. Como estamos usando una aplicación de consola, agregaremos una llamada a ReadLine para que la aplicación siga ejecutándose una vez abierto el host. También crearemos el host mediante una instrucción Using para asegurarnos de que se cierra y se elimina correctamente al cerrarse la aplicación de consola. Antes usamos MathService, así que ahora, para este proyecto, usaremos HelloService.

using System.ServiceModel;

static void Main(string[] args)

{

    Type t = typeof(ServiceLib.HelloService);

    using (ServiceHost host = new ServiceHost(t))

    {

        host.Open();

 

        Console.WriteLine("Service Started …");

        Console.ReadLine();               

    }

}

Configuración del servicio

Es posible que haya observado que, al configurar los hosts, no indicamos la manera en la que el cliente debe comunicarse con el servicio. Pues bien, esto se consigue mediante la configuración del servicio. Y aunque la configuración puede especificarse por medio de código, lo más habitual será hacerlo mediante XML en un archivo .config.

Para que un cliente pueda comunicarse con un servicio, se necesita un extremo. Un extremo está formado por tres componentes: una dirección, un enlace y un contrato. Éstos son los componentes fundamentales de WCF. La dirección es el URI que identifica dónde puede encontrarse el servicio. El enlace se usa para definir las reglas de la comunicación (por ejemplo, la codificación, si los mensajes necesitan ser protegidos, la manera en la que el servicio autenticará al cliente, etc.). Finalmente, el contrato define las operaciones expuestas por el servicio. Se trata básicamente de una referencia a la clase de servicio.

WCF dispone de varios enlaces integrados configurados para usos empresariales habituales (consulte la tabla que hay a continuación). Es posible personalizar estos enlaces mediante su configuración, aunque también es posible crear enlaces personalizados propios para adaptarlos a las necesidades del sistema. Para no complicar demasiado el proceso, usaremos el enlace básico HTTP, que sigue el protocolo SOAP 1.1.

 

Binding integrated

  

 

Ahora necesitaremos configurar los hosts. Empezaremos con la aplicación de consola. En primer lugar necesitamos un sitio para colocar la información de configuración, de modo que agregaremos un archivo app.config. Haga clic con el botón secundario en el proyecto y elija Add | New Item. A continuación, cree un archivo de configuración de la aplicación usando el nombre predeterminado (app.config).

Para configurar el extremo, se necesita una dirección, un enlace y un contrato. Veamos estos componentes en su orden inverso. El contrato ya quedó determinado a través del tipo de contrato que proporcionamos al constructor ServiceHost Para nuestra aplicación, será ServiceLib.IHello.. El enlace será basicHttpBinding, tal como ya mencionamos antes. Para la dirección usaremos "http://localhost:8081/HelloService&quot;,lo que significa que los clientes deberán enviar los mensajes a través del protocolo HTTP al puerto 8081 del servidor local usando HelloService como el nombre de aplicación. 

Para usar el asistente para la creación del proxy que se describe en la sección siguiente, debemos realizar un paso adicional. A diferencia de los servicios web ASP.NET, los servicios WCF no exponen una descripción del servicio (ni los metadatos) de forma automática. Por lo tanto, para habilitar esta característica, necesitamos agregar un comportamiento del servicio e indicarle a éste que use este comportamiento nuevo.

Reemplace todo el contenido del archivo app.config con el documento XML que se muestra a continuación para así configurar el host de consola.

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <behaviors>

      <serviceBehaviors>

        <behavior name="mexEnabled">

          <serviceMetadata httpGetEnabled="true"

                           httpGetUrl="http://localhost:8081/HelloService" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <services>

 <service behaviorConfiguration="mexEnabled" name="ServiceLib.HelloService">

        <endpoint address="http://localhost:8081/HelloService"

                  binding="basicHttpBinding"

                  contract="Service.IHello"></endpoint>

      </service>

    </services>

  </system.serviceModel>

</configuration>

La configuración del host web es prácticamente igual. Las diferencias son que la configuración XML se realiza en el archivo web.config, que no es necesario indicar una dirección para el extremo (ésta se determinará a través de la dirección del archivo Service.svc del servidor web) y que el contrato que el host web expone es MathService, no HelloService.

Configuración del cliente y proxy

Ya estamos preparados para crear la aplicación cliente. Haga clic con el botón secundario en la solución, elija Add | New Project, y cree una aplicación de Windows denominada ServiceClient.

wcf_intro_05

Para poder consumir los servicios, es necesario que configuremos antes el cliente y los proxy. Esta configuración es casi igual que la del servidor, ya que se requiere que un extremo sea compatible con los hosts del servicio. Los proxy son las clases del proyecto del cliente que se usan para representar los servicios; de esta manera permiten llamar las operaciones del servicio mediante una forma de tipos inflexible.

Afortunadamente, las extensiones de Visual Studio para .NET 3.0 incluyen un asistente que creará la configuración y los proxy necesarios mediante los metadatos del servicio. Lo único que se necesita es la dirección URL correcta del host del servicio.

Empecemos por el servicio de hospedaje web:

Para configurar el cliente para poder usar este servicio y crear la clase de proxy, haga clic con el botón secundario en el proyecto ServiceClient y elija la opción para agregar una referencia de servicio. Escriba la dirección URL del servicio para el Servicio URI y MathProxy para el nombre de la referencia del servicio y, a continuación, haga clic en Aceptar.

wcf_intro_06

Verá como la aplicación cliente ahora tiene un archivo app.config además de un archivo MathProxy en la carpeta denominada Service References.

Para el servicio hospedado en la consola, la dirección URL necesaria para tener acceso a los metadatos del servicio está almacenada en el archivo app.config. Si observa el atributo httpGetUrl del elemento serviceMetadata, verá que se configuró para http://localhost:8081/HelloService.

Antes de actualizar el cliente mediante el asistente para agregar referencias de servicio, debemos iniciar el host. Haga clic con el botón secundario en el proyecto ConsoleServiceHost y elija Debug | Start New Instance.

Cuando se esté ejecutando el host, haga clic con el botón secundario en el proyecto ServiceClient, elija la opción para agregar una referencia de servicio y escriba el URI adecuado en el campo del URI del servicio y HelloProxy para el nombre de la referencia del servicio.

Al abrir el archivo app.config en el proyecto ServiceClient, verá el archivo XML que se generó con el asistente. Para facilitar los ajustes de la configuración, el asistente coloca diversos atributos en el archivo junto con los valores predeterminados de configuración. Dado que no es necesario incluir los atributos con los valores predeterminados en la configuración, se puede simplificar el documento XML como el que se muestra a continuación.

La configuración contiene un elemento extremo para cada host, y los atributos de la dirección y del enlace de estos elementos coinciden con los valores de los hosts. Lo que sí es diferente es el contrato. Esto se debe a que el cliente no establece referencias con la clase original del servicio, sino que, en lugar de eso, establece referencias con un proxy del cliente generado por el asistente a partir de los metadatos del servicio.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.serviceModel>

    <client>

      <endpoint  address="http://localhost:13419/WebServiceHost/Service.svc"

        binding="basicHttpBinding"

        contract="MathProxy.MathService"

        name="BasicHttpBinding_MathService" />

      <endpoint

        address="http://localhost:8081/HelloService"

        binding="basicHttpBinding"

        contract="HelloProxy.IHello"

        name="BasicHttpBinding_IHello" />

    </client>

  </system.serviceModel>

</configuration>

 

Advertisements
Development

RSS en C#.Net

Primero, Que es RSS?

 

RSS ( Really Simple Syndication )


RSS es un sencillo formato de datos que es utilizado para redifundir contenidos a suscriptores de un sitio web. El formato permite distribuir contenido sin necesidad de un navegador, utilizando un software diseñado para leer estos contenidos RSS. A pesar de eso, es posible utilizar el mismo navegador para ver los contenidos RSS. Las últimas versiones de los principales navegadores permiten leer los RSS sin necesidad de software adicional.

RSS es parte de la familia de los formatos XML desarrollado específicamente para todo tipo de sitios que se actualicen con frecuencia y por medio del cual se puede compartir la información y usarla en otros sitios web o programas. A esto se le conoce como redifusión web. dicho de otro modo, el estándar RSS propone el formato en que la información (por ejemplo las noticias de un periódico o los artículos en un blog) debe mostrarse de cara al público. No se trata más que de otro "dialecto" XML.

 

Por ejemplo, imaginemos que tenemos una Web con una sección sobre noticias relacionadas con la Premier League y la Champion League. Por la filosofía de nuestra página, queremos compartir las noticias de modo que cualquiera pueda tener acceso a éstas sin necesidad de acceder a la Web. Para ello no tenemos más que proporcionar estas noticias en formato RSS, de modo que pueda ser leído tanto por programas lectores (llamados comúnmente agregadores) como por otros webmasters que decidan incorporar esas noticias en sus propias Webs.

Este acrónimo se usa para referirse a los siguientes estándares:

·         Rich Site Summary (RSS 0.91)

·         RDF Site Summary (RSS 0.9 y 1.0)

·         Really Simple Syndication (RSS 2.0)

·         Además es usual que el término RSS sea usado indistintamente para referirse a cualquiera de los formatos RSS o Atom.

Gracias a los agregadores o lectores de feeds (programas o sitios que permiten leer fuentes web) se pueden obtener resúmenes de todos los sitios que se desee desde el escritorio del sistema operativo, programas de correo electrónico o por medio de aplicaciones web que funcionan como agregadores. No es necesario abrir el navegador y visitar decenas de webs.

La redifusión web no es sólo un fenómeno vinculado a los weblogs, aunque han ayudado mucho a su popularización.

Para una completa especificación del formato RSS 2.0, puedes visitar http://www.rssboard.org/rss-specification

Elementos de Canal
Mostraremos los campos que definen al RSS en general. Los tres primero son obligatorios, el resto opcionales:
title: Es el título que le daremos a nuestro documento RSS y con el que se dará a conocer en cualquier lector de RSS.
link: enlace a la página a la que se refiere el documento RSS. En nuestro ejemplo mostramos un enlace a éste Blog: http://jonnathandeveloper2008.spaces.live.com.
– description: algo sencillito y descriptivo de lo que se puede encontrar en este RSS, como por ejemplo: "Blog ASP.NET 2.0 con C# en castellano".
ttl: sugiere la cantidad de minutos que debería ser cacheada la información. Es como decirle al lector de RSS "en tantos minutos no suelo añadir más información, por lo que puedes dejarlo en tu cache".
language: idioma en que está escrita la información.
generator: el programa o algoritmo que ha creado el RSS.


Elementos de Item
Vayamos ahora con los elementos Item. En nuestro ejemplo se trataría de los artículos
title: título del artículo, y que será lo primero que se muestre en un lector RSS.
link: url del artículo, de modo que desde el lector se pueda viajar hacia la fuente original del artículo.
description: en nuestro ejemplo es el texto completo del artículo, pero habitualmente no suelen ser más que las primeras líneas. La idea es que el  que lea sobre un lector RSS se interese sobre la noticia y posteriormente enlace al artículo original mediante link.
pubDate: representa la fecha y hora en que el artículo fue escrito. Debe estar en el formato de tipo "Fri, 05 Jan 2007 20:50:08 GMT". Esto se consigue con aplicando ToString("R") al DateTime correspondiente.
guid: representa a un identificador global único… y aquí se acaba el estándar. Los lectores RSS lo van a ver como un string, y nosotros somos quienes nos debemos de preocupar de que este identificador sea único. Por ejemplo, yo he decidido que, dado que cada artículo representa una única URL, el guid sea esa misma url.

Como has visto en las especificaciones oficiales, hay más elementos de RSS, pero son opcionales.

La clase RSS
Ahora sólo nos queda la tarea de hacer unas clases C# que respondan convenientemente a la estructura de RSS.
En líneas generales, tenemos tres clases: RSS, RSSChannel y RSSItem.

RSS tiene un único elemento Channel, y éste tiene como propiedades los elementos de canal y un listado genérico de RSSItem. En RSSItem encontraremos las propiedades que representan los elementos del Item.

Leer y escribir RSS
En el mismo fichero de descarga habréis visto dos ficheros ".cs": RSS.cs y RSSBLL.cs

RSS.cs contiene las tres clases de las que hemos hablado. Fijaos que se han añadido algunos atributos XML a las propiedades de las clases (XmlElement, XmlRoot y XmlIgnore)… ¿qué es eso?

Para leer y mostrar el fichero RSS vamos utilizar la clase XmlSerializer, ubicada dentro del namespace System.Xml.Serialization.

XmlSerializer hace un poquito de magia, que nos facilita el trabajo tremendamente. Dándole el tipo de una clase, es capaz de mostrarnos su equivalente XML, y viceversa: rellenar una instancia de la clase a partir de un XML.

Aplicado a nuestro ejemplo, veremos que a partir de la clase RSS, el XmlSerializer lo transformará en un fichero RSS mediante su método "Serialize"; y también, a partir de cualquier fichero RSS, rellenará una instancia a un objeto RSS mediante su método "Deserialize".

¿Y cómo hace esto? XmlSerialize utiliza propiedades de refactoring, es decir, que lee los metadatos para saber el nombre de las propiedades de una clase, su tipo, etc. Y ahí viene lo que comentábamos con lo de los atributos XML (XmlElement, XmlRoot y XmlIgnore), pues de alguna forma debemos decirle al XmlSerializer que la propiedad pubdate_DateTime no la muestre por XML o que la raíz del XML es "rss" y no "RSS".

algo del código:

public static void writeRSS(RSS rss)

{

XmlSerializer ser = new XmlSerializer(typeof(RSS));

StringBuilder sb = new StringBuilder();

using (StringWriter sw = new StringWriter(sb))

{

using (XmlTextWriter writer = new XmlTextWriter(sw))

{

writer.Formatting = Formatting.Indented;

ser.Serialize(sw, rss);

}

}

HttpResponse response = HttpContext.Current.Response;

response.Clear();

response.ContentType = "text/plain";

response.Write(sb.ToString());

response.Flush();

response.End();

}

public static RSS readRSS(string url)

{

RSS rss = new RSS();

XmlSerializer ser = new XmlSerializer(typeof(RSS));

using (XmlTextReader reader = new XmlTextReader(url))

{

try

{

rss = ser.Deserialize(reader) as RSS;

}

catch (Exception e)

{

HttpContext.Current.Response.Write(e.Message);

}

}

return rss;

}

Development

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>