Aggiungi questo metodo di estensione al tuo codice:
public static Uri UrlOriginal(this HttpRequestBase request)
{
string hostHeader = request.Headers["host"];
return new Uri(string.Format("{0}://{1}{2}",
request.Url.Scheme,
hostHeader,
request.RawUrl));
}
E poi puoi eseguirlo fuori dalla RequestContext.HttpContext.Request
proprietà.
C'è un bug (può essere modificato, vedi sotto) in Asp.Net che si presenta su macchine che usano porte diverse dalla porta 80 per il sito Web locale (un grosso problema se i siti Web interni sono pubblicati tramite bilanciamento del carico su IP virtuale e le porte vengono utilizzate internamente per le regole di pubblicazione) in base alle quali Asp.Net aggiungerà sempre la porta sulla AbsoluteUri
proprietà, anche se la richiesta originale non la utilizza.
Questo codice assicura che l'URL restituito sia sempre uguale all'URL originariamente richiesto dal browser (inclusa la porta - come verrebbe incluso nell'intestazione host) prima che avvenga qualsiasi bilanciamento del carico ecc.
Almeno, lo fa nel nostro ambiente (piuttosto contorto!) :)
Se ci sono dei proxy stravaganti tra questi che riscrivono l'intestazione host, allora non funzionerà neanche.
Aggiornamento del 30 luglio 2013
Come menzionato da @KevinJones nei commenti seguenti, l'impostazione che cito nella prossima sezione è stata documentata qui: http://msdn.microsoft.com/en-us/library/hh975440.aspx
Anche se devo dire che non riuscivo a farlo funzionare quando l'ho provato, ma potrei essere solo io a fare un refuso o qualcosa del genere.
Aggiornamento del 9 luglio 2012
L'ho trovato poco fa e intendevo aggiornare questa risposta, ma non l'ho mai fatto. Quando è arrivata una votazione su questa risposta, ho pensato che avrei dovuto farlo ora.
Il 'bug' che cito in Asp.Net può essere controllato con un valore appSettings apparentemente non documentato - chiamato 'aspnet:UseHostHeaderForRequest'
- cioè:
<appSettings>
<add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>
Mi sono imbattuto in questo mentre guardavo HttpRequest.Url
in ILSpy - indicato dalla --->
sinistra sulla seguente copia / incolla da quella vista ILSpy:
public Uri Url
{
get
{
if (this._url == null && this._wr != null)
{
string text = this.QueryStringText;
if (!string.IsNullOrEmpty(text))
{
text = "?" + HttpEncoder.CollapsePercentUFromStringInternal(text,
this.QueryStringEncoding);
}
---> if (AppSettings.UseHostHeaderForRequestUrl)
{
string knownRequestHeader = this._wr.GetKnownRequestHeader(28);
try
{
if (!string.IsNullOrEmpty(knownRequestHeader))
{
this._url = new Uri(string.Concat(new string[]
{
this._wr.GetProtocol(),
"://",
knownRequestHeader,
this.Path,
text
}));
}
}
catch (UriFormatException)
{ }
}
if (this._url == null) { /* build from server name and port */
...
Personalmente non l'ho usato - è privo di documenti e quindi non è garantito che rimanga - tuttavia potrebbe fare la stessa cosa che ho menzionato sopra. Per aumentare la pertinenza nei risultati di ricerca - e riconoscere qualcun altro che sembra averlo scoperto - l' 'aspnet:UseHostHeaderForRequest'
impostazione è stata citata anche da Nick Aceves su Twitter