How to get current page URL in MVC 3

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


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