tags:

views:

2274

answers:

7

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?

+1  A: 

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  A: 

Better yet, extend the UrlHelper - doh!

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

:-)

Charlino
I would add also optional parameters for this solution.This should cover all cases.
Jenea
+1  A: 

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  A: 

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

The ASP.NET MVC RC1 source code 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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }
     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, requestUrl.Authority);
      }

     }
    }
81bronco
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
A: 

Maybe this (?):

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>
tytusse
+2  A: 

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, "http");
Adam Boddington
Interesting, so if you specify the protocol, the URL is absolute
Casebash
I think this is the right answer.
rudimenter
A: 
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>
Aros