253

I need to do something like this:

<script type="text/javascript">
    token_url = "http://example.com/your_token_url";
</script>

I'm using the Beta version of MVC, but I can't figure out how to get the absolute url of an action. I'd like to do something like this:

<%= Url.AbsoluteAction("Action","Controller")) %>

Is there a helper or Page method for this?

AdamMc331
  • 16,492
  • 10
  • 71
  • 133
Mike Comstock
  • 6,640
  • 10
  • 36
  • 41

9 Answers9

505

Click here for more information, but esentially there is no need for extension methods. It's already baked in, just not in a very intuitive way.

Url.Action("Action", null, null, Request.Url.Scheme);
Misha Huziuk
  • 170
  • 4
  • 18
Adam Boddington
  • 6,750
  • 2
  • 21
  • 12
  • 7
    Interesting, so if you specify the protocol, the URL is absolute – Casebash Aug 02 '10 at 22:49
  • 25
    This answer is the better one, this way Resharper can still validate that the Action and Controller exists. I would suggest the use of Request.Url.Scheme instead of the http, that way http and https are both supported. – Pbirkoff Mar 16 '12 at 10:25
  • 2
    @Pbirkoff, agree that this is the best answer but you might like to know that you can annotate your own methods for ReSharper to know that parameters represent actions/controllers. In that way R# can still validate the strings you provide, as it does so well. – Drew Noakes Aug 08 '12 at 22:34
  • 3
    A small improvement could be to replace **"http"** with `Request.Url.Scheme` so that if you use HTTPS the url generated will also use HTTPS. – Erik Schierboom Dec 15 '12 at 11:25
  • 1
    This works for `Html.ActionLink` as well (any of the methods that take a protocol, the last 2 in MVC 4 for example) – Christopher Jun 13 '13 at 03:14
  • Here's a quick summary post that also includes Url.Content http://benjii.me/2015/05/get-the-absolute-uri-from-asp-net-mvc-content-or-action/ – Ben Cull May 20 '15 at 08:24
  • Your link is dead now. – Vitor Canova Apr 13 '16 at 11:27
  • 1
    I wish answers like this would use examples. This answer is useless to me as wouldn't have a clue how to use it in a script for example as the OP had. – BMills Jul 23 '16 at 09:58
  • @Bmills This could be used in a controller, in a server tag in a view, or anywhere else that you have defined `URL` as a `UrlHelper` instance. How to get it into your script depends on what you're doing. You could place it in a hidden field that the script accesses, or return it in an AJAX response. – xr280xr Jan 24 '19 at 14:13
  • In razor pages Url.Action("Action", null, null, Context.Request.Scheme); – Paulo Neves Dec 18 '19 at 19:07
74

Extend the UrlHelper

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this UrlHelper url, string action, string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

Then call it like this

<%= Url.AbsoluteAction("Dashboard", "Account")%>

EDIT - RESHARPER ANNOTATIONS

The most upvoted comment on the accepted answer is This answer is the better one, this way Resharper can still validate that the Action and Controller exists. So here is an example how you could get the same behaviour.

using JetBrains.Annotations

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(
            this UrlHelper url,
            [AspMvcAction]
            string action,
            [AspMvcController]
            string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

Supporting info:

Charlino
  • 15,802
  • 3
  • 58
  • 74
  • 3
    I would add also optional parameters for this solution. This should cover all cases. – Eugeniu Torica May 27 '09 at 14:54
  • Very nice! I used this code but I made the only argument relativeUrl so that the caller can create it using whatever Url method they like (router values etc), and your method can just be responsible for making it relative. So mine is: AbsoluteUrl(this UrlHelper url, string relativeUrl). – Rob Kent Nov 30 '11 at 16:41
27
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>
Ryan Sampson
  • 6,717
  • 12
  • 47
  • 55
21

Using @Charlino 's answer as a guide, I came up with this.

The ASP.NET MVC documentation for UrlHelper shows that Url.Action will return a fully-qualified Url if a hostname and protocol are passed in. I created these helpers to force the hostname and protocol to be provided. The multiple overloads mirror the overloads for Url.Action:

using System.Web.Routing;

namespace System.Web.Mvc {
    public static class HtmlExtensions {

        public static string AbsoluteAction(this UrlHelper url, string actionName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, new RouteValueDictionary(routeValues), 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, routeValues, requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, routeValues, requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, object routeValues, 
                                            string protocol) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), protocol, null);
        }

    }
}
radbyx
  • 9,352
  • 21
  • 84
  • 127
Raleigh Buckner
  • 8,343
  • 2
  • 31
  • 38
  • 4
    Thx for the code, helped me a lot, but there is an issue with this solution that usually comes up during development. If the site is hosted on a specific port, the port information is included in *requestUrl.Authority*, like *localhost:4423*. For some reason the Action method appends the port again. So either this is a bug inside the Action Method or you are not supposed to supply the port here. But which of the available Properties on the request is the right one (DnsSafeHost or Host)? Well the solution is rather simple: Just supply *null* and the Action method will fill in the right value. – ntziolis Sep 14 '10 at 15:56
  • I've updated the answer to incorporate @ntziolis's suggestion. – Andrew Arnott Sep 22 '12 at 20:59
5

Complete answer with arguments would be :

var url = Url.Action("ActionName", "ControllerName", new { id = "arg_value" }, Request.Url.Scheme);

and that will produce an absolute url

Dashrath
  • 2,141
  • 1
  • 28
  • 33
3

I'm not sure if there is a built in way to do it, but you could roll your own HtmlHelper method.

Something like the following

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this HtmlHelper html, string actionUrl)
        {
            Uri requestUrl = html.ViewContext.HttpContext.Request.Url;

            string absoluteAction = string.Format("{0}://{1}{2}",
                                                  requestUrl.Scheme,
                                                  requestUrl.Authority,
                                                  actionUrl);

            return absoluteAction;
        }
    }
}

Then call it like this

<%= Html.AbsoluteAction(Url.Action("Dashboard", "Account"))%> »

HTHs, Charles

Charlino
  • 15,802
  • 3
  • 58
  • 74
1

Same result but a little cleaner (no string concatenation/formatting):

public static Uri GetBaseUrl(this UrlHelper url)
{
    Uri contextUri = new Uri(url.RequestContext.HttpContext.Request.Url, url.RequestContext.HttpContext.Request.RawUrl);
    UriBuilder realmUri = new UriBuilder(contextUri) { Path = url.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
    return realmUri.Uri;
}

public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName)
{
    return new Uri(GetBaseUrl(url), url.Action(actionName, controllerName)).AbsoluteUri;
}
veggerby
  • 8,940
  • 2
  • 34
  • 43
0

Maybe this (?):

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>
tytusse
  • 11
  • 1
0

env: dotnet core version 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
guhyeon
  • 566
  • 6
  • 8