提问



我在我正在建立的博客上使用Facebook评论插件。它有一些FBXML标记,由页面上引用的facebook javascript解释。


这一切都很好,但我必须将当前的,完全限定的URL传递给插件。


<div style="width: 900px; margin: auto;">
    <div id="fb-root"></div>
    <fb:comments href="URL HERE" num_posts="10" width="900"></fb:comments>
</div>


获取当前页面的URL的最佳方法是什么?请求URL。


解决方案



这是我的解决方案的最终代码:


<fb:comments href="@Request.Url.AbsoluteUri" num_posts="15" width="900"></fb:comments>

最佳参考


您可以使用Request.RawUrlRequest.Url.OriginalStringRequest.Url.ToString()Request.Url.AbsoluteUri[27] [28]

其它参考1


将此扩展方法添加到您的代码中:


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(包括端口 - 因为它将包含在主机头中),然后再进行任何负载平衡等操作。


至少,它确实在我们(相当复杂!)的环境中:)


如果在它们之间有任何重写主机头的任何时髦代理,那么这也不会起作用。


2013年7月30日更新


正如@KevinJones在下面的评论中所提到的 - 我在下一节中提到的设置已在此处记录:http://msdn.microsoft.com/en-us/library/hh975440.aspx [29]


虽然我不得不说当我尝试它时我无法工作 - 但这可能只是我犯了一个错字或其他东西。


2012年7月9日更新


我不久前遇到过这个问题,并且想要更新这个答案,但从未这样做过。当一个upvote刚刚进入这个答案我认为我现在应该这样做。


我在Asp.Net中提到的bug可以通过一个明显未记录的appSettings值来控制 - 称为'aspnet:UseHostHeaderForRequest' - 即:


<appSettings>
  <add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>


我在查看ILSpy中的HttpRequest.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 */
       ...


我个人没有使用它 - 它没有记录,所以因此不能保证坚持 - 但它可能会做我上面提到的相同的事情。为了提高搜索结果的相关性 - 并承认其他人已经发现了这一点 - 'aspnet:UseHostHeaderForRequest'设置也被Twitter上的Nick Aceves提及[30]

其它参考2


public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}

其它参考3


Request.Url.PathAndQuery


应该完美,特别是如果你只想要相对的Uri(但保持查询字符串)

其它参考4


我也是出于Facebook的原因寻找这个,到目前为止所给出的答案都没有按照需要或太复杂。


@Request.Url.GetLeftPart(UriPartial.Path)


获取完整的协议,主机和路径没有查询字符串。如果您使用的是默认值80以外的其他内容,还包括端口。

其它参考5


我的最爱...


Url.Content(Request.Url.PathAndQuery)


要不就...


Url.Action()

其它参考6


在其他答案中没有提到的一件事是区分大小写,如果它将在多个地方被引用(它不是在原始问题中,但是值得考虑,因为这个问题出现在很多类似的搜索中)。基于其他答案,我发现以下最初对我有用:


Request.Url.AbsoluteUri.ToString()


但为了更可靠,这成了:


Request.Url.AbsoluteUri.ToString().ToLower()


然后根据我的要求(检查访问该站点的域名并显示相关内容):


Request.Url.AbsoluteUri.ToString().ToLower().Contains("xxxx")

其它参考7


对我来说问题是当我尝试访问Controller的构造函数中的HTTPContextHTTPContext还没有准备好。当在Index方法中移动它时它起作用:


var uri = new Uri(Request.Url.AbsoluteUri);
url = uri.Scheme + "://" + uri.Host + "/";enter code here