Internet, Intranet e le redirezioni

Un thread nato oggi sul newsgroup Microsoft dedicato ad ASP .NET mi ha riportato alla mente un argomento spesso trascurato. Una delle FAQ più classiche riguardanti ASP .NET (o lo sviluppo web in generale) è sicuramente: "Come faccio a redirigere l'utente ad una pagina differente mediante codice lato server?" La risposta tipica è: "Usa Response.Redirect". Risposta corretta, per carità, ma con una piccola "trappola": questo metodo invia al client lo status code http 302 il cui codice mnemonico è "Found", ossia spostato temporaneamente. Questo è un classico caso nel quale lo sviluppo di applicazioni intranet (o comunque private) differisce da quello orientato a Internet. Perchè? Perchè i motori di ricerca interpretano questa informazione come "temporanea", poichè lo status code http dedicato alle redirezioni permanenti è il 301 (Moved Permanently) e quindi non aggiornano con uguale efficacia i propri indici. Come risolvere questa situazione? Considerato che la classe HttpResponse è sealed, e quindi ci scordiamo estensione e polimorfismo (sarebbe stato troppo comodo poter utilizzare sempre una ipotetica classe HttpResponseEx), non possiamo far altro che creare una classe ad hoc:

public class RequestRedirector
{
   
public void PermanentRedirect(string url)
    {
        PermanentRedirect(url,
true);
   
}

   
public void PermanentRedirect(string url, bool endResponse)
    {
       
if(url==null)
           
throw new ArgumentNullException("URL cannot be null");
       
else if(url==string.Empty)
           
throw new ArgumentException("URL cannot be empty");
       
else if(url.IndexOf("\n")>=0)
           
throw new ArgumentException("URL cannot contain newline");
       
else
       
{
             url =
new System.Uri(HttpContext.Current.Request.Url, url, true).AbsoluteUri;
             HttpContext.Current.Response.ClearHeaders();
             HttpContext.Current.Response.ClearContent();
             HttpContext.Current.Response.StatusCode = 301;
             HttpContext.Current.Response.AppendHeader("Location", url);
             HttpContext.Current.Response.Write("\r\n");
             HttpContext.Current.Response.Write("

Object moved to here.

\r\n");
             HttpContext.Current.Response.Write("\r\n");
        }
       
if(endResponse)
            HttpContext.Current.Response.End();
    }
}

Utilizzabile poi con un semplice:

RequestRedirector redirector = new RequestRedirector();
redirector.PermanentRedirect("targetform.aspx",
false);

Morale della favola: ASP .NET astrae moltissimo lo sviluppatore dai dettagli di basso livello, ma conoscere http è sempre un buon investimento. :-)

posted @ lunedì 13 settembre 2004 16.02

Print

Comments on this entry:

# re: Internet, Intranet e le redirezioni

Left by Adrian Florea at 13/09/2004 17.08
Gravatar
Interessante.

Vorrei fare solo una piccolissima osservazione, rubata da questo post di Brad Abrams (http://blogs.msdn.com/brada/archive/2004/02/15/73535.aspx):

al posto di ArgumentNullException("URL cannot be null") mettere ArgumentNullException("null", "URL cannot be null")

# re: Internet, Intranet e le redirezioni

Left by Adrian Florea at 13/09/2004 17.11
Gravatar
Scusami, per la fretta ho postato il commento con "null" al posto di "url". Quindi:

ArgumentNullException("url", "URL cannot be null")"

# Inviare il codice HTTP 404 per le risorse non presenti

Left by Daniele Bochicchio at 13/09/2004 19.27
Gravatar

# Redirezione permanente di una pagina...non

Left by Luke.NET at 14/09/2004 8.27
Gravatar

# re: Internet, Intranet e le redirezioni

Left by Max at 14/09/2004 18.10
Gravatar

# Dubbi

Left by Federico Dal Maso at 14/09/2004 19.24
Gravatar
Usare un Server.Transfer non semplifica la vita?

Si evita in toto un roundtrip all'utente (il 302) e si ritorna al primo colpo la response corretta. O no?

# RE: Internet, Intranet e le redirezioni

Left by Andrea Saltarello at 15/09/2004 0.48
Gravatar
Federico, più che semplificare la vita usare Server.Transfer nel caso esposto è una soluzione "semplicistica". Se ciò che vuoi fare è comunicare allo user agent (non necessariamente un browser) che la risorsa richiesta ha permanentemente cambiato URL beh... Allora la soluzione tecnicamente corretta è inviare uno status code 301. Volendo, potremmo inviare lettera di formale protesta al sig Berners-Lee, ma non credo servirebbe a molto :-)

# re: Internet, Intranet e le redirezioni

Left by Federico Dal Maso at 15/09/2004 16.29
Gravatar
Conosco il 301, ma per com'era posta la domanda ("Come faccio a redirigere l'utente ad una pagina differente mediante codice lato server?") non mi sembrava vi fossero necessità di permanenza! ;)

Cmq ti ricordo che esistono anche dei moduli da agganciare alla pipeline che rimappano interamente l'url in modo anche dinamico, in stile Apache. Rewrite.NET ad esempio. Se l'intero sito è costruito così, il problema non sussiste. La risorsa logica esposta dall'url rimane la stessa e basta rimapparla internamente. Se proprio non c'è più torni il 404.

# re: Internet, Intranet e le redirezioni

Left by Andrea Saltarello at 15/09/2004 17.12
Gravatar
Federico, IMVHO per come era posta la domanda la risposta data è funzionale, standard, di facile applicazione e sufficientemente generica. Il metodo Transfer è limitato dalla impossibilità di fornire contenuti ospitati da applicazioni differenti e gli handler/moduli (ad esempio, proprio Rewrite.NET) di redirezione sono lontani dalle pratiche comuni e dalla "paura" diffusa di "mettere mano" al file di configurazione. In un "mondo" che ha fatto e continua a fare largo uso del metodo Redirect, creare una versione "estesa" di quest'ultimo è forse la soluzione + naturale.
Quando arriverà ASP .NET 2.0 forse la cultura del "URL-rewriting-out-of-the-box" diverrà "roba di tutti i giorni", ma da quel momento ci separano ancora parecchi mesi e (ahinoi) chissà quanti (ulteriori) tagli dalla feature list.

# Blogs: li abbiamo

Left by StrangeLog - Il blog di Andrea S at 11/10/2004 12.21
Gravatar

# Blogs: li abbiamo

Left by StrangeLog - Il blog di Andrea S at 11/10/2004 12.23
Gravatar

Your comment:



 (will not be displayed)


 
 
 
Please add 6 and 2 and type the answer here:
 

Live Comment Preview:

 
«febbraio»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213