如何在MVC 3中获取当前页面URL

时间:2011-03-14 21:29:08

标签: c# asp.net asp.net-mvc razor

我在我正在建立的博客上使用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>

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

解决方案

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

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

10 个答案:

答案 0 :(得分:506)

您可以使用Request.RawUrlRequest.Url.OriginalStringRequest.Url.ToString()Request.Url.AbsoluteUri

答案 1 :(得分:47)

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

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属性上添加端口 - 即使原始请求不使用它。

此代码确保返回的网址始终等于浏览器最初请求的网址(包括端口 - 因为它将包含在主机标头中),然后再进行任何负载平衡等操作

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

如果介于重写主机标头之间有任何时髦的代理,那么这也无效。

2013年7月30日更新

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

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

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 */
       ...

我个人还没有使用它 - 它没有文档,因此不能保证坚持下去 - 但它可能会做同样的事我上面提到过。为了提高搜索结果的相关性 - 并承认其他人已经发现了这一点 - the 'aspnet:UseHostHeaderForRequest' setting has also been mentioned by Nick Aceves on Twitter

答案 2 :(得分:12)

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

答案 3 :(得分:11)

Request.Url.PathAndQuery

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

答案 4 :(得分:8)

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

@Request.Url.GetLeftPart(UriPartial.Path)

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

答案 5 :(得分:4)

我最喜欢的......

Url.Content(Request.Url.PathAndQuery)

或只是......

Url.Action()

答案 6 :(得分:1)

对于完整 URL 的 Core 3.0,这对我有用:

$"{Request.Scheme}://{Request.Host.Value}{Request.Path.Value}"

答案 7 :(得分:0)

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

Request.Url.AbsoluteUri.ToString()

但为了更可靠,这就成了:

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

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

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

答案 8 :(得分:0)

对我来说,问题是当我在HTTPContext尚未就绪时尝试访问Controller的构造函数中的HTTPContext时。当在Index方法中移动时,它起作用了:

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

答案 9 :(得分:0)

浏览器历史记录的情况(单页样式)

HttpContext.Request.UrlReferrer