Adicione este método de extensão ao seu código:
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 então você pode executá-lo fora da RequestContext.HttpContext.Request
propriedade.
Existe um bug (pode ser evitado, veja abaixo) no Asp.Net que surge em máquinas que usam portas diferentes da porta 80 para o site local (um grande problema se sites internos forem publicados via balanceamento de carga no IP virtual e ports são usados internamente para publicar regras), em que o Asp.Net sempre adiciona a porta à AbsoluteUri
propriedade - mesmo que a solicitação original não a utilize.
Esse código garante que a URL retornada seja sempre igual à URL solicitada originalmente pelo navegador (incluindo a porta - como seria incluída no cabeçalho do host) antes que qualquer balanceamento de carga etc. ocorra.
Pelo menos, acontece em nosso ambiente (bastante complicado!) :)
Se houver proxies descolados que reescrevam o cabeçalho do host, isso também não funcionará.
Atualização 30 de julho de 2013
Conforme mencionado por @ KevinJones nos comentários abaixo - a configuração mencionada na próxima seção foi documentada aqui: http://msdn.microsoft.com/en-us/library/hh975440.aspx
Embora eu tenha que dizer que não consegui fazê-lo funcionar quando tentei - mas isso poderia ser apenas eu cometendo um erro de digitação ou algo assim.
Atualização 9 de julho de 2012
Me deparei com isso há pouco tempo e pretendia atualizar essa resposta, mas nunca o fiz. Quando um voto positivo apareceu nesta resposta, pensei que deveria fazê-lo agora.
O 'bug' mencionado no Asp.Net pode ser controlado com um valor appSettings aparentemente não documentado - chamado 'aspnet:UseHostHeaderForRequest'
- ou seja:
<appSettings>
<add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>
Me deparei com isso enquanto olhava no HttpRequest.Url
ILSpy - indicado pelo --->
lado esquerdo da seguinte cópia / pasta a partir dessa exibição do 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 */
...
Eu pessoalmente não o usei - não é documentado e, portanto, não é garantido que permaneça por aqui - no entanto, pode fazer a mesma coisa que mencionei acima. Para aumentar a relevância nos resultados de pesquisa - e reconhecer alguém que parece ter descoberto isso - a 'aspnet:UseHostHeaderForRequest'
configuração também foi mencionada por Nick Aceves no Twitter