402

I am using the Facebook comments plugin on a blog I am building. It has some FBXML tags that are interpreted by the facebook javascript that is referenced on the page.

This all works fine, but I have to pass in the current, fully-qualified URL to the plugin.

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

What is the best way to get the URL of the current page? The request URL.

Solution

Here is the final code of my solution:

<fb:comments href="@Request.Url.AbsoluteUri" num_posts="15" width="900"></fb:comments>
Shaun Wilson
  • 8,727
  • 3
  • 50
  • 48
CatDadCode
  • 58,507
  • 61
  • 212
  • 318

10 Answers10

578

You could use the Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString() or Request.Url.AbsoluteUri.

Shaun Wilson
  • 8,727
  • 3
  • 50
  • 48
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 3
    For some reason, this doesn't seem to get the entire URL, just everything after the domain. – CatDadCode Mar 14 '11 at 21:31
  • 6
    @Chevex, how about `Request.Url.ToString()` or `Request.Url.AbsoluteUri`? – Darin Dimitrov Mar 14 '11 at 21:32
  • Note that Request.RawUrl and Request.Url could be different if the Url has been rewritten. – Yuriy Faktorovich Mar 14 '11 at 21:34
  • 9
    Almost. `Request.Url.AbsoluteUri` did it :) – CatDadCode Mar 14 '11 at 21:34
  • @Chevex & @Darin - please note there is a bug in `AbsoluteUri` whereby the local port for the website is always used, even if the original request didn't specify the same port - see my answer for details. – Andras Zoltan Mar 14 '11 at 21:43
  • `AbsoluteUri` is implemented on my live code right now. Scanning the generated URL in the page source shows no sign of a port number. – CatDadCode Mar 14 '11 at 21:46
  • 2
    @Chevex - what port is the site hosted on? If it's port 80 then, yes, you won't see one. I'm saying that in an environment where there's a virtual IP publishing port 80 to one or more machines on a *different* port (e.g. 81) then Asp.Net will always add :81 to the Url incorrectly – Andras Zoltan Mar 14 '11 at 21:52
  • Ah, well then no worries. It's on a hosting server through Arvixe Hosting. It will always be on port 80. – CatDadCode Mar 14 '11 at 21:55
  • NOTE: If your website is in a virtual directory such that the base URL of any page is like http://webdomain.com/webapp, none of these solutions will give you that base url that you will need to build on to formulate a page url. – nuander Jun 28 '12 at 21:04
  • 30
    to get samples of the different url fragments have a look at: http://www.cambiaresearch.com/articles/53/how-do-i-get-paths-and-url-fragments-from-the-httprequest-object – ms007 Apr 26 '13 at 09:44
  • None of these samples fully function as needed. For the facebook comments plugin you do not need the query string. See below for method without getting the query string. http://stackoverflow.com/questions/5304782/how-to-get-current-page-url-in-mvc-3/31869297#31869297 – johnw182 Aug 07 '15 at 03:40
  • This will give me current `Url`. I am making an ajax request, and I want the `Url` which is in the _Url bar_ and not the current `Url`. Is it possible to get it in the action-method or I need to retrieve it using `js` and pass it to the new action-method. – phougatv Dec 05 '16 at 08:43
49

Add this extension method to your code:

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));
}

And then you can execute it off the RequestContext.HttpContext.Request property.

There is a bug (can be side-stepped, see below) in Asp.Net that arises on machines that use ports other than port 80 for the local website (a big issue if internal web sites are published via load-balancing on virtual IP and ports are used internally for publishing rules) whereby Asp.Net will always add the port on the AbsoluteUri property - even if the original request does not use it.

This code ensures that the returned url is always equal to the Url the browser originally requested (including the port - as it would be included in the host header) before any load-balancing etc takes place.

At least, it does in our (rather convoluted!) environment :)

If there are any funky proxies in between that rewrite the host header, then this won't work either.

Update 30th July 2013

As mentioned by @KevinJones in comments below - the setting I mention in the next section has been documented here: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Although I have to say I couldn't get it work when I tried it - but that could just be me making a typo or something.

Update 9th July 2012

I came across this a little while ago, and meant to update this answer, but never did. When an upvote just came in on this answer I thought I should do it now.

The 'bug' I mention in Asp.Net can be be controlled with an apparently undocumented appSettings value - called 'aspnet:UseHostHeaderForRequest' - i.e:

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

I came across this while looking at HttpRequest.Url in ILSpy - indicated by the ---> on the left of the following copy/paste from that ILSpy view:

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

I personally haven't used it - it's undocumented and so therefore not guaranteed to stick around - however it might do the same thing that I mention above. To increase relevancy in search results - and to acknowledge somebody else who seeems to have discovered this - the 'aspnet:UseHostHeaderForRequest' setting has also been mentioned by Nick Aceves on Twitter

Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160
  • ok so where or how are you getting man instance of HttpRequestBase lets say if you weren't working with code directly in a controller for example? – PositiveGuy Jan 27 '12 at 07:36
  • @CoffeeAddict Well, in mvc3 you have HttpContext.Current.Request, since Asp.net 4 uses the base abstractions. If on .net 3.5 or lower, you can use HttpRequestWrapper around the same property, from System.Web.Abstractions – Andras Zoltan Jan 27 '12 at 07:43
  • 3
    Very late to this but the UseHostHeaderForRequestUrl is documented here http://msdn.microsoft.com/en-us/library/hh975440.aspx – Kevin Jones Sep 16 '12 at 21:29
  • good spot! at least they finally added it for 4.5 documentation! – Andras Zoltan Sep 17 '12 at 05:57
17
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Brian Ogden
  • 18,439
  • 10
  • 97
  • 176
14
Request.Url.PathAndQuery

should work perfectly, especially if you only want the relative Uri (but keeping querystrings)

Lucius
  • 430
  • 4
  • 8
9

I too was looking for this for Facebook reasons and none of the answers given so far worked as needed or are too complicated.

@Request.Url.GetLeftPart(UriPartial.Path)

Gets the full protocol, host and path "without" the querystring. Also includes the port if you are using something other than the default 80.

johnw182
  • 1,349
  • 1
  • 16
  • 22
  • Great find! I suspect this didn't exist at the time of asking? I feel like I would have seen that :) – CatDadCode Aug 07 '15 at 16:57
  • I thought I saw where this was just added but I just checked and it seems it has been there since .NET 1.1. Who knows. – johnw182 Aug 09 '15 at 22:22
5

My favorite...

Url.Content(Request.Url.PathAndQuery)

or just...

Url.Action()
Carter Medlin
  • 11,857
  • 5
  • 62
  • 68
4

This worked for me for Core 3.0 for full URL:

$"{Request.Scheme}://{Request.Host.Value}{Request.Path.Value}"
tdahman1325
  • 210
  • 3
  • 6
1

One thing that isn't mentioned in other answers is case sensitivity, if it is going to be referenced in multiple places (which it isn't in the original question but is worth taking into consideration as this question appears in a lot of similar searches). Based on other answers I found the following worked for me initially:

Request.Url.AbsoluteUri.ToString()

But in order to be more reliable this then became:

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

And then for my requirements (checking what domain name the site is being accessed from and showing the relevant content):

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

Lyall
  • 1,367
  • 3
  • 17
  • 42
  • That doesn't make it "more reliable". Whether lowercasing it is useful depends entirely on what you're actually trying to do, and why case-sensitivity would make sense there. Usually you _do_ want the URL to be case-sensitive. – CodeCaster Aug 25 '16 at 10:12
  • 1
    @CodeCaster Yeah the term 'more reliable' was based on my own experience, as I definitely do NOT want the URLs to be case sensitive as it causes no end of problems for clients. – Lyall Aug 25 '16 at 10:53
1

For me the issue was when I tried to access HTTPContext in the Controller's constructor while HTTPContext is not ready yet. When moved inside Index method it worked:

var uri = new Uri(Request.Url.AbsoluteUri);
url = uri.Scheme + "://" + uri.Host + "/";enter code here
hkutluay
  • 6,794
  • 2
  • 33
  • 53
boateng
  • 910
  • 11
  • 21
0

The case (single page style) for browser history

HttpContext.Request.UrlReferrer
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35