Este sencillo ejemplo mostrará como implementar un controlador de peticiones HTTP personalizado para servir una imagen a modo de CAPTCHA. Naturalmente esto es solo un punto de partida muy simple y se podría complicar más para, por ejemplo, construir un control de servidor tipo CAPTCHA.
Para implementar nuestro controlador de peticiones HTTP personalizado debemos utilizar la interfaz IHttpHandler. Esta interfaz define el contrato que deben tener todos los tipos que se utilicen para manejar las peticiones HTTP. De esta forma podemos decidir qué y cómo se devuelve la solicitud desde el servidor.
A continuación dejo el código de la clase que implementa esta funcionalidad.
public class CaptchaHandler : IHttpHandler
{
public static string RndTexto { get; set; }
private char[] Abc;
public CaptchaHandler()
{
Abc = new char[]{
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','Ñ','O','P','Q','R','S',
'T','U','V','W','X','Y','Z'};
InitRndTexto();
}
//Creamos un texto aleatorio de 6 letras.
private void InitRndTexto()
{
Random Rnd = new Random();
System.Text.StringBuilder Sb = new System.Text.StringBuilder();
for (int i = 0; i < 6; i++)
{
Sb.Append(Abc[Rnd.Next(0, 27)]);
}
RndTexto = Sb.ToString();
}
#region Miembros de IHttpHandler
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
Bitmap Imagen = new Bitmap(180, 80, PixelFormat.Format16bppRgb555);
Graphics Grafico = Graphics.FromImage(Imagen);
//Escribimos el texto.
Font Fuente = new Font(new FontFamily("Chiller"), 35, FontStyle.Italic);
Grafico.DrawString(RndTexto, Fuente, Brushes.Red, 10, 15);
//Dibujamos dos lineas.
for (int i = 0; i < 2; i++)
{
Point A = new Point(5, (35 + i * 10));
Point B = new Point(175, (35 + i * 10));
Grafico.DrawLine(new Pen(Brushes.Black, 3), A, B);
}
context.Response.ContentType = "Image/jpeg";
Imagen.Save(context.Response.OutputStream, ImageFormat.Jpeg);
}
#endregion
}
No hay mucho que explicar. En primer lugar generamos un texto aleatorio y lo guardamos en el campo RndTexto. Este campo publico podrá ser utilizado por otra clase cliente para comprobar, por ejemplo, que el texto introducido por el usuario coincide con el de la imagen. Después escribimos el texto aleatorio sobre una superficie de dibujo. También dibujamos dos lineas horizontales para dificultar un poco su lectura.
Debemos registrar en el web.config este controlador HTTP para que ASP.NET sepa que debe hacer cuando entra una petición en el servidor.
<system.web>
<httpHandlers>
<add verb="*" type="CaptchaHandler" path="*.captcha"/>
</httpHandlers>
</system.web>
Con esta configuración estamos indicando (por orden) que para cualquier tipo de petición GET o POST, debe ser manejada por el tipo CaptchaHandler. Por último, indicamos que cuando se solicite un archivo con extensión captcha nuestro controlador debe actuar sirviendo la respuesta implementada en el código.
Desde este momento, siempre que el código cliente solicite una imagen con la extensión indicada, se le servirá nuestro CAPTCHA personalizado. Es decir, al encontrarse con algo como lo siguiente:
<img alt="" src="sitioWeb.captcha" />
Obtendremos una salida en el explorador cliente como esta.
Quizás el diseño no sea muy acertado, pero dejo para vosotros el mejorarlo. 