Добавьте этот метод расширения к вашему коду:
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));
}
И затем вы можете выполнить его из свойства RequestContext.HttpContext.Request
.
В Asp.Net существует ошибка (может быть обойдена стороной, см. Ниже), которая возникает на машинах, которые используют порты, отличные от порта 80, для локального веб-сайта (большая проблема, если внутренние веб-сайты публикуются с помощью балансировки нагрузки на виртуальном IP и порты используются внутренне для правил публикации), при этом Asp.Net будет всегда добавлять порт в свойстве AbsoluteUri
- даже если исходный запрос не использует его.
Этот код гарантирует, что возвращаемый URL-адрес всегда будет равен URL-адресу, который браузер первоначально запросил (включая порт - как он будет включен в заголовок узла), прежде чем произойдет какая-либо балансировка нагрузки и т. Д.
По крайней мере, это происходит в нашей (довольно запутанной!) Среде:)
Если между ними есть какие-нибудь прикольные прокси, которые переписывают заголовок хоста, то это тоже не сработает.
Обновление от 30 июля 2013 г.
Как упомянуто @KevinJones в комментариях ниже - настройка, о которой я упоминаю в следующем разделе, была задокументирована здесь: http://msdn.microsoft.com/en-us/library/hh975440.aspx
Хотя я должен сказать, что не смог заставить его работать, когда попробовал - но это может быть просто я сделал опечатку или что-то в этом роде.
Обновление от 9 июля 2012 года
Я сталкивался с этим некоторое время назад и хотел обновить этот ответ, но так и не сделал. Когда на этот ответ только что пришли возражения, я подумал, что должен сделать это сейчас.
«Ошибка», о которой я упоминаю в Asp.Net, может управляться явно недокументированным значением appSettings - так называемым 'aspnet:UseHostHeaderForRequest'
- т.е.:
<appSettings>
<add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>
Я сталкивался с этим, глядя на HttpRequest.Url
в ILSpy - обозначенном --->
слева от следующей копии / вставки из этого представления 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 */
...
Лично я не использовал его - он недокументирован и, следовательно, не гарантированно останется поблизости - однако он может сделать то же самое, что я упомянул выше. Чтобы повысить релевантность результатов поиска и признать кого-то, кто, кажется, обнаружил это, параметр 'aspnet:UseHostHeaderForRequest'
также упоминается Ником Эйсевесом в Twitter