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


360

我正在建立的博客上使用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的最佳方法是什么?请求网址。

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

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

Answers:


533

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


2
由于某种原因,这似乎并不能获取整个URL,而只能获取域之后的所有URL。
CHEV

6
@Chevex,怎么样Request.Url.ToString()还是Request.Url.AbsoluteUri
Darin Dimitrov

9
几乎。Request.Url.AbsoluteUri做到了:)
CHEV

2
@Chevex-网站托管在哪个端口上?如果是端口80,是的,您将看不到端口80。我是说,在那里有一个虚拟IP端口发布80到一个或多个机器上对环境的不同端口(例如81),那么Asp.Net会随时添加:81到URL错误
安德拉斯·佐尔坦

29
以获得不同的URL片段的样本看看:cambiaresearch.com/articles/53/...
ms007

48

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

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/zh-cn/library/hh975440.aspx

尽管我不得不说尝试时无法使它工作-但这可能只是我在打错字或其他内容。

2012年7月9日更新

不久前,我碰到了这个问题,打算更新此答案,但从未成功。当刚刚对这个答案发表意见时,我认为我现在应该这样做。

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

我个人没有使用过它-它没有证件,因此不能保证能坚持使用-但是它可能会执行我上面提到的相同操作。为了提高搜索结果的相关性-并承认其他人似乎已经发现了这一点-Nick Aceves在Twitter上也提到了'aspnet:UseHostHeaderForRequest'设置


好的,那么您在哪里或如何获得HttpRequestBase的实例,例如,您是否不是直接在控制器中使用代码?
PositiveGuy

@CoffeeAddict好吧,在mvc3中,您拥有HttpContext.Current.Request,因为Asp.net 4使用了基本抽象。如果在.net 3.5或更低版本上,则可以在System.Web.Abstractions
Andras Zoltan 2012年

3
对此很晚,但是UseHostHeaderForRequestUrl在此处记录了msdn.microsoft.com/en-us/library/hh975440.aspx
Kevin Jones

好地方!至少他们最终为4.5文档添加了它!
安德拉斯·佐坦

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

12
Request.Url.PathAndQuery

应该可以完美地工作,特别是如果您只想要相对的Uri(但保留查询字符串)


8

我也是出于Facebook的原因而寻找此信息,到目前为止,给出的答案都无法按需工作或过于复杂。

@Request.Url.GetLeftPart(UriPartial.Path)

获取完整的协议,主机和“无”查询字符串的路径。如果您使用的不是默认值80,则还包括端口。


很棒的发现!我怀疑在提出问题时这还不存在?我觉得我会看到的:)
Chev

我以为我看到了刚刚添加的内容,但是我刚刚检查了一下,看来它从.NET 1.1开始就已经存在了。谁知道。
johnw182

4

我的最爱...

Url.Content(Request.Url.PathAndQuery)

要不就...

Url.Action()

Url.Action()仅提供网址的右侧,如果您需要完整的完整网址怎么办?
阿洛克

1

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

Request.Url.AbsoluteUri.ToString()

但是为了更可靠,它变成了:

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

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

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


但这并不能使其“更加可靠”。将其改写是否有用完全取决于您实际要执行的操作以及为什么区分大小写在这里有意义。通常,您确实希望URL区分大小写。
CodeCaster

1
@CodeCaster是的,“更可靠”一词是基于我的经验,因为我绝对不希望URL区分大小写,因为它不会给客户带来麻烦。
莱尔,2016年

0

对我来说,问题是当我还没有准备好尝试访问HTTPContextController的构造函数时HTTPContext。当移入Index方法内部时,它可以工作:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.