How do I find the absolute url of an action in ASP.NET MVC?
Asked Answered
R

9

255

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?

Rorie answered 12/1, 2009 at 6:26 Comment(0)
G
507

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);
Giusto answered 18/6, 2010 at 2:54 Comment(10)
Interesting, so if you specify the protocol, the URL is absoluteWaldenses
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.Collage
@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.Monopolist
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.Klug
This works for Html.ActionLink as well (any of the methods that take a protocol, the last 2 in MVC 4 for example)Newlin
Here's a quick summary post that also includes Url.Content benjii.me/2015/05/…Capet
Your link is dead now.Neile
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.Whelp
@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.Agamete
In razor pages Url.Action("Action", null, null, Context.Request.Scheme);Rafaelof
F
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:

Federica answered 12/1, 2009 at 10:26 Comment(2)
I would add also optional parameters for this solution. This should cover all cases.Thirzia
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).Sapienza
P
27
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>
Posturize answered 2/7, 2010 at 19:23 Comment(0)
T
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);
        }

    }
}
Theorist answered 17/3, 2009 at 15:1 Comment(2)
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.Gomes
I've updated the answer to incorporate @ntziolis's suggestion.Bonesetter
C
6

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

Catamite answered 17/1, 2018 at 7:42 Comment(0)
F
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

Federica answered 12/1, 2009 at 10:18 Comment(0)
R
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;
}
Roseroseann answered 12/1, 2009 at 18:52 Comment(0)
H
0

Maybe this (?):

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>
Hitherto answered 23/11, 2009 at 14:8 Comment(0)
H
0

env: dotnet core version 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
Hasson answered 30/8, 2017 at 5:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.