在代码中添加以下扩展方法:
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中有一个bug(可以绕过,见下文)。Net在使用端口而不是端口80的机器上产生(如果内部网站通过虚拟IP上的负载平衡发布,并且端口用于内部发布规则,这是一个大问题)。Net将始终在AbsoluteUri属性上添加端口——即使原始请求没有使用它。
这段代码确保返回的url总是等于浏览器最初请求的url(包括端口——因为它将包含在主机头中),然后才发生任何负载平衡等。
至少,它在我们的(相当复杂!)环境中是这样的:)
如果有任何奇怪的代理之间重写主机头,那么这也不会工作。
2013年7月30日更新
正如@KevinJones在下面的评论中提到的-我在下一节中提到的设置已经记录在这里:http://msdn.microsoft.com/en-us/library/hh975440.aspx
虽然我不得不说,当我尝试它的时候,我不能让它工作-但那可能只是我打错了或别的什么。
2012年7月9日更新
不久前我偶然发现了这个问题,并打算更新这个答案,但一直没有。当这个答案得到好评时,我想我应该现在就做。
我在Asp中提到的“bug”。Net可以用一个明显没有记录的appSettings值来控制-称为'aspnet:UseHostHeaderForRequest' -即:
<appSettings>
<add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>
我在查看HttpRequest时遇到了这个。ILSpy中的Url -由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 */
...
我个人没有使用过它——它没有文件,因此不能保证一直存在——但是它可能会做我上面提到的同样的事情。为了增加搜索结果的相关性,并感谢其他人发现了这一点,Nick Aceves在Twitter上也提到了“aspnet:UseHostHeaderForRequest”设置