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", "URL cannot be null");
else if(url==string.Empty)
throw new ArgumentException("url", "URL cannot be empty");
else if(url.IndexOf("\n")>=0)
throw new ArgumentException("url", "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("<html><head><title>Object moved</title></head><body>\r\n");
HttpContext.Current.Response.Write("<h2>Object moved to <a href='" + HttpUtility.HtmlEncode(url) + "'>here</a>.</h2>\r\n");
HttpContext.Current.Response.Write("</body></html>\r\n");
}
if(endResponse)
HttpContext.Current.Response.End();
}
} Utilizzabile poi con un semplice:
RequestRedirector redirector =
new RequestRedirector();
redirector.PermanentRedirect("targetform.aspx", false);