asp - asp.net - aspcode.it

COMMUNITY - Login
 Username:
 
 Password:
 
Voglio registrarmi!
Password dimenticata?
 Utenti on-line: 0
 Ospiti on-line: 5861
ASPCode.it - Store

  > > Articoli

Url rewriting tramite HttpHandler

Data di pubblicazione: 30/08/2005        Voto della community: 3,67 (Votanti: 3)

Questo articolo mostra il modo in cui approfittare delle funzionalità degli HttpHandler per la creazione di un sistema di url rewriting per le vostre applicazioni web ASP.NET; questo semplice sistema ci permette di esporre al pubblico delle url più "amichevoli", più facili quindi da memorizzare e più utili per quanto riguarda l'indicizzazione nei motori di ricerca.
Quindi, un url del genere:

http://www.peppedotnet.it/post.aspx?id=1

la possiamo far diventare:

http://www.peppedotnet.it/post1.aspx

o addirittura

http://www.peppedotnet.it/Blog/primo_post.aspx

Questi tipi di url sono decisamente più "user-friendly", sia per l'utente che per i robot dei motori di ricerca (google impazzisce per url di questo genere...:).

Per far ciò bisogna utilizzare quelle classi fornite dal .NET Framework per soddisfare le richieste HTTP in ingresso. Queste classi, che ci permettono la creazione di HttpHandler personalizzati, derivano tutte dall'interfaccia System.Web.IHttpHandler, e ne implementano il metodo ProcessRequest(), utile a processare la richiesta HTTP, e la proprietà IsReusable, che specifica se e quando è supportata una attività di pooling.
E' inoltre possibile implementare degli HttpHandler, creandone un'istanza, attraverso l'implementazione dell'interfaccia IHttpHandlerFactory, interfaccia che permette un controllo più fine e accurato sulla richiesta. IHttpHandlerFactory fornisce, in pratica, l'infrastruttura che gestisce l'effettiva risoluzione ed elaborazione delle richieste URL alle istanze IHttpHandler.
Questa interfaccia espone due metodi:
  • GetHandler - Restituisce un nuovo oggetto di tipo IHttpHandler che elabora la richiesta.
  • ReleaseHandler - Permette ad altri oggetti di utilizzare un'istanza gia esistente dell'HttpHandler.
L'HttpHandler creato come esempio, è stato appunto creato implementando questa classe.

using System;
using System.IO;
using System.Web;
using System.Web.UI;

namespace Peppe.Handlers
{
  public class NewsHttpHandler : IHttpHandlerFactory
  {
    public IHttpHandler GetHandler(HttpContext context,
                 string requestType,
                 string url,
                 string pathTranslated)
    {
      context.Items["fileName"] = Path.GetFileNameWithoutExtension(url);
      return PageParser.GetCompiledPageInstance(url,
            context.Server.MapPath("default.aspx"),
            context);
    }

    public void ReleaseHandler(IHttpHandler handler)
    {
    }
  }
}

Nel listato si vede effettivamente il lavoro fatto dal metodo GetHandler, metodo che prende in input 4 parametri:
  • context - Istanza della classe HttpContext della richiesta corrente.
  • requestType - Il tipo della richiesta effettuata (GET o POST).
  • url - L'url della richiesta.
  • pathTranslated - Il percorso fisico della risorsa richiesta.
E' stato solamente aggiunto il codice necessario per salvare il nome della pagina richiesta all'interno dell'istanza della classe HttpContext, in modo tale da poterlo riutilizzare nella pagina ASP.NET che effettivamente risolve la richiesta, e la chiamata al metodo GetCompiledPageInstance della classe System.Web.UI.PageParser, che specifica la pagina fisica che risolve la richiesta e ne restituisce il gestore HTTP.

Nota: è importante ricordarsi di compilare gli HttpHandler al di fuori della soluzione Visual Studio .NET della vostra applicazione ASP.NET, in quanto non sembrano funzionare all'interno.

Per far ciò non bisogna far altro che utilizzare, da riga di comando, il compilatore (nel nostro caso C#) fornito dal framework in questo modo:

csc /t:library /r:System.dll,System.Web.dll /out:Peppe.Handlers.dll /recurse:*.cs

Una volta creato l'handler, e dopo averlo inserito tra i riferimenti del vostro progetto, bisogna settarne le proprietà via web.config e creare la pagina, che nel nostro caso e la pagina default.aspx, utile a risolvere la richiesta e a stampare a video le informazioni desiderate.
Un HttpHandler nel file di configurazione della vostra applicazione viene settato in questo modo:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation defaultLanguage="c#" debug="true" />
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <httpHandlers>
      <add verb="*" path="News/*.aspx"
       type="Peppe.Handlers.NewsHttpHandler, Peppe.Handlers" />
    </httpHandlers>
  </system.web>
</configuration>

Il fulcro sta nell'attributo "path" dell'elemento "add", il cui contenuto ci permette di decidere il formato delle nostre nuove url. Il nostro path (News/*.aspx) sta a significare che tutte le url che hanno qualsiasi nome tra lo slash e il .aspx, vengono gestite dal nostro HttpHandler. Quindi tutte le url di questo genere:

http://www.vostrosito.it/News/qui_ci_metto_quello_che_voglio.aspx

Se, per esempio, avessimo inserito un path del genere: News/news*.aspx, avremmo scelto di utilizzare url di questo tipo:

http://www.vostrosito.it/News/news51.aspx

Vediamo ora come creare la pagina fisica che, effettivamente, risolve la richiesta HTTP in ingresso.
Non dobbiamo far altro che creare una nuova Web Form ASP.NET sotto la cartella /News, e fare in modo che nell'evento Page_Load ci sia la lettura dell'url richiesta e la successiva visualizzazione dei dati relativi.
Nell'esempio sviluppato, ho scelto di avere un campo del database che contenesse il nome della pagina riscritta, in modo tale da fare una semplice query di equivalenza tra il valore del campo e la pagina aspx richiesta. Magari questa tecnica non è il massimo parlando di sicurezza di dati, ma non era questo il punto dell'articolo.
Vediamo quindi il codice che legge l'url richiesta e visualizza i dati:

protected System.Web.UI.WebControls.Label lbl;
private OleDbConnection conn = null;

private void Page_Load(object sender, System.EventArgs e)
{
  string pageName = Request.Url.Segments[Request.Url.Segments.Length-1];
  string strConn = ConfigurationSettings.AppSettings["strConn"];
  string sql = "SELECT * FROM News WHERE PageName='"+pageName+"'";
  try
  {
    using(conn = new OleDbConnection(strConn))
    {
      conn.Open();
      OleDbCommand cmd = new OleDbCommand();
      cmd.Connection = conn;
      cmd.CommandText = sql;
      cmd.CommandType = CommandType.Text;
      OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
      DataSet ds = new DataSet();
      adapter.Fill(ds, "News");
      DataTable dt = ds.Tables["News"];
      foreach(DataRow riga in dt.Rows)
      {
        Response.Write("<h2>"+riga["Titolo"].ToString()+"</h2>");
        Response.Write(riga["Corpo"].ToString());
      }
    }
  }
  catch(Exception exe)
  {
    lbl.Text = exe.Message;
  }
}

Chiaramente questo è solo un esempio introduttivo all'argomento degli HttpHandler, argomento che risulta decisamente utile a tutti gli sviluppatori ASP.NET.
Nel seguente file da scaricare troverete il codice sorgente utile per vedere l'applicazione in funzione.

Link utili:
Riscrittura url in ASP.NET
Creating HttpHandler
How ASP.NET web pages are processed on the web server
Interfaccia IHttpHandler
Interfaccia IHttpHandlerFactory

Si ringrazia PeppeDotNet.it per la gentile concessione dell'articolo.




Utenti connessi: 5861