How to get current page URL in MVC 3

C#asp.netasp.net MvcRazor

C# Problem Overview


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>

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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

Solution 3 - C#

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

Solution 4 - C#

Request.Url.PathAndQuery

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

Solution 5 - C#

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.

Solution 6 - C#

My favorite...

Url.Content(Request.Url.PathAndQuery)

or just...

Url.Action()

Solution 7 - C#

This worked for me for Core 3.0 for full URL:

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

Solution 8 - C#

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")

Solution 9 - C#

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

Solution 10 - C#

The case (single page style) for browser history

HttpContext.Request.UrlReferrer

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChevView Question on Stackoverflow
Solution 1 - C#Darin DimitrovView Answer on Stackoverflow
Solution 2 - C#Andras ZoltanView Answer on Stackoverflow
Solution 3 - C#Brian OgdenView Answer on Stackoverflow
Solution 4 - C#LuciusView Answer on Stackoverflow
Solution 5 - C#johnw182View Answer on Stackoverflow
Solution 6 - C#Carter MedlinView Answer on Stackoverflow
Solution 7 - C#tdahman1325View Answer on Stackoverflow
Solution 8 - C#LyallView Answer on Stackoverflow
Solution 9 - C#boatengView Answer on Stackoverflow
Solution 10 - C#Hamit YILDIRIMView Answer on Stackoverflow