Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Gli HTTP Handler di ASP.NET

Scrivere e sfruttare gli HttpHandler per intercettare le richieste ed associare funzioni a percorsi particolari
Scrivere e sfruttare gli HttpHandler per intercettare le richieste ed associare funzioni a percorsi particolari
Link copiato negli appunti

Gli HTTP Handler sono tra i meccanismi alla base dell'architettura di ASP.NET, in quanto si occupano di elaborare le risposte a specifiche richieste HTTP e fornirle, secondo la forma più consona, al richiedente.

Esistono, infatti, handler predefiniti per gestire richieste a pagine ASP.NET (.aspx) e a web service (.asmx), altri invece per bloccare la visualizzazione di alcuni file speciali (come il file web.config) o per abilitate il meccanismo del tracing. Oltre a questi, l'alto grado di estensibilità di ASP.NET ci permette di creare HTTP Handler personalizzati per ogni tipo di richiesta che vogliamo gestire in maniera differente dalle altre.

In poche parole, anche voi, senza saperlo, avete sempre utilizzato degli HTTP Handler nelle vostre applicazioni, in quanto ogni richiesta effettuata alle risorse del vostro sito, viene gestita con il suo specifico handler.

Tecnicamente però, un HTTP Handler non è altro che una classe .NET che implementa l'interfaccia IHttpHandler (reperibile sotto il namespace System.Web). Tale interfaccia espone un metodo utile a processare la richiesta HTTP in entrata (il metodo ProcessRequest) e una proprietà, di tipo boolean, utile a decidere se l'istanza dell'HTTP Handler corrente può essere utilizzata o meno da altre richieste (la proprietà IsReusable). Chiaramente, è proprio attraverso l'implementazione di questa interfaccia che noi possiamo sviluppare gli handler utili a svolgere le funzionalità custom di cui abbiamo bisogno.

Per visualizzare gli handler predefiniti e per registrare quelli creati da noi, è presente un'apposita sezione all'interno dello schema dei file di configurazione validi per le applicazioni web basate sul .NET Framework. Questa è rappresentata dall'elemento <httpHandlers />, figlio diretto di <system.web />.

L'elenco degli handler di default è visibile all'interno del web.config del server, raggiungibile seguendo il percorso C:WINDOWSMicrosoft.NETFrameworkVx.x.xxxxxCONFIG; questo file contiene le configurazioni di base per tutti i siti gestiti da IIS ed la dichiarazione degli handler di default è posta a questo livello, quindi, perché possa interessare tutte le applicazioni web installate sul server.

All'interno del web.config specifico per la nostra applicazione, ritroviamo la stessa sezione di configurazione utile a rimuovere handler predefiniti che non vogliamo utilizzare oppure a registrare handler custom da noi sviluppati.

Questi i principali HTTP Handler utilizzati dal framework di ASP.NET:

  • Page Handler - handler per la gestione delle pagine .aspx. Rappresentato dalla classe: System.Web.UI.PageHandlerFactory
  • Web Service Handler - handler per la gestione dei web service. Rappresentato dalla classe: System.Web.Services.Protocols.WebServiceHandlerFactory
  • Http Forbidden Handler - per bloccare le richieste a file particolari della nostra applicazione web. Rappresentato dalla classe: System.Web.HttpForbiddenHandler
  • Static File Handler - hanlder per la rappresentazione di un file così com'è, senza alcun tipo di modifica lato server. Rappresentato dalla classe: System.Web.StaticFileHandler
  • Trace Handler - per la funzionalità di trace dell'applicazione (file trace.axd). Rappresentato dalla classe: System.Web.Handlers.TraceHandler

Oltre a questi, come abbiamo detto, abbiamo la possibilità di estendere la pipeline di ogni richiesta HTTP effettuata verso specifiche risorse, sviluppando i nostri HTTP Handler personalizzati, compilandoli in appositi assembly e registrandoli all'interno del file web.config del nostro sito web.

La creazione di un HTTP Handler personalizzato

Vediamo ora come creare il nostro primo HTTP Handler custom. Come abbiamo detto, un handler è rappresentato da una classe .NET che, come unico ma fondamentale vincolo, deve implementare l'interfaccia IHttpHandler. Per comodità, possiamo inserire questa classe nella directory App_Code, senza dover creare un assembly apposta.

Il cuore di un HTTP Handler è rappresentato dal metodo ProcessRequest; tale metodo prende come parametro il contesto della richiesta HTTP corrente, in modo tale da darci la possibilità di agire direttamente sulla richiesta che gestisce.

Come primo esempio, creiamo un handler che stampi a video una frase (il classico Hello World, per intenderci).

using System;
using System.Web;

public class HelloWorldHandler : IHttpHandler
{
  public bool IsReusable
  {
    get { return false; }
  }

  public void ProcessRequest(HttpContext context)
  {
    context.Response.Write("Hello World !");
  }
}

Una volta inserita questa classe nella directory App_Code, abbiamo bisogno di registrare l'handler nel file di configurazione dell'applicazione, dichiarandone il tipo, i metodi HTTP cui questo handler risponde (GET, POST, etc.) e il path da esso gestito. Per far ciò, dobbiamo inserire nella sezione <httpHandlers /> un elemento "add", ovvero una direttiva che permette di aggiungere il nostro handler con le informazioni riguardanti il gestore.

<system.web>
  <httpHandlers>
    <add type="HelloWorldHandler" verb="*" path="HelloWorld.html" />
  </httpHandlers>
</system.web>

Il nostro primo HTTP Handler è stato dichiarato per gestire ogni tipo di richiesta verso il file "HelloWorld.aspx"; questo file non esiste fisicamente sul server, ma è stato "mappato" dal nostro handler. La cosa bella è la possibilità di mappare con alcuni HTTP Handler tutti i percorsi gestiti da IIS, quindi pagine web (.aspx, .html, etc…), immagini (.jpg, .gif, etc.) o il contenuto di intere directory, questo sempre ammesso che il nostro web server ci permetta di farlo. Purtroppo alcuni servizi di hosting limitano la gestione dei path solo alle estensioni più note di ASP.NET.

Se vogliamo creare un HTTP Handler personalizzato, senza doverlo inserire in un assembly specifico e senza doverlo registrare nel web.config dell'applicazione, possiamo avvalerci di un file con estensione .ashx, estensione predefinita per gli HTTP Handler generici. Tale file sarà segnato dalla direttiva iniziale "WebHandler" e conterrà una classe .NET che implementa l'interfaccia IHttpHandler (perché non è possibile creare degli handler senza ereditare da tale interfaccia).

Il nostro handler generico, che non fa altro che stampare a video una frase in formato file di testo, avrà quindi questa forma:

<%@ WebHandler Language="C#" Class="HandlerGenerico" %>

using System;
using System.Web;

public class HandlerGenerico : IHttpHandler
{
  public bool IsReusable
  {
    get { return false; }
  }

  public void ProcessRequest (HttpContext context)
  {
    context.Response.ContentType = "text/plain";
    context.Response.Write("Hello World, from HTTP Handler !");
  }
}

Un esempio più complesso

Vediamo ora, in che modo possiamo avvalerci degli HTTP Handler di ASP.NET per aggiungere delle funzionalità un po' più complesse e di grande impatto al nostro sito web.

Come esempio, possiamo creare un gestore in grado di mappare tutte le richieste HTTP a tutti i file con estensione ".jpg" presenti in una specifica directory; come funzionalità aggiunta, tali immagini verranno decorate con un testo che indica la data di creazione del file (questa tecnica di firmare le immagini è detta watermark, ed è molto utile per coprire le proprie risorse grafiche con il copyright).

Per raggiungere il nostro scopo, ci dobbiamo avvalere di alcune classi del namespace System.Drawing, in modo da permetterci di manipolare l'immagine e salvarla nello stream della risposta HTTP.

public class ImageHandler : IHttpHandler
{
  public bool IsReusable
  {
    get { return false; }
  }

  public void ProcessRequest(HttpContext context)
  {
    // prelevo informazioni su file fisico richiesto
    Bitmap b = new Bitmap(context.Request.PhysicalPath);
    FileInfo fi = new FileInfo(context.Request.PhysicalPath);
    Graphics g = Graphics.FromImage(b);

    // imposto l'allineamento della stringa da stampare (in fondo a destra)
    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Far;
    format.LineAlignment = StringAlignment.Far;

    // disegno la stringa
    g.DrawString(fi.CreationTime.ToLongDateString(),
        new Font("Verdana", 20, FontStyle.Bold),
        Brushes.Orange,
        new Rectangle(10, 10, b.Width - 10, b.Height - 10), format);
  
    g.Dispose();

    // salvo la stringa nel buffer di risposta
    b.Save(context.Response.OutputStream, ImageFormat.Jpeg);
    b.Dispose();
  }
}

Dopo aver inserito questo handler nella directory App_Code dell'applicazione web, lo registriamo nel web.config:

<system.web>
  <httpHandlers>
    <add type="HelloWorldHandler" verb="*" path="HelloWorld.html" />
    <add type="ImageHandler" verb="*" path="Images/*.jpg" />
  </httpHandlers>
</system.web>

In questo modo, tutte le richieste alle immagini jpeg presenti nella directory "/Images", saranno segnate con la data della loro creazione.

Conclusioni

Questa è solo una breve panoramica riguardo le tecniche disponibili per la creazione e l'utilizzo degli HTTP Handler di ASP.NET; utili implementazioni sono legate ad argomenti come l'url rewriting, il watermarking sulle immagini o semplicemente sulla realizzazione di filtri su specifiche richieste HTTP. Per un esempio di url rewriting tramite http Handler questo tutorial.

Gli HTTP Handler, inoltre, svolgono una funzione molto simile a quella che è propria dei filtri ISAPI di IIS, con la differenza che hanno la possibilità di essere gestiti direttamente all'interno dell'applicazione web prescelta, senza dover metter mano alle configurazioni del web server, cosa che non è sempre possibile in ambienti di produzione.
Chiaramente, gli sviluppi possibili legati agli HTTP Handler sono veramente infiniti e dettati dall'immaginazione dello sviluppatore.

Ti consigliamo anche