How to Build Absolute Action URLs Using the UrlHelper Class
Building action URLs using the UrlHelper class that ships with ASP.NET MVC is very convenient. Razor views can call the UrlHelper.Action() helper method like this:
@* Generates the URL /Home/About *@
@Url.Action("About", "Home")
However, UrlHelper.Action() only generates relative URLs when it is called the way shown above. You might ask why you would want to choose absolute URLs over relative ones. Relative URLs are perfectly fine — as long as they are used directly on your website. Problems arise if you want to provide, for example, an RSS feed because the items' <link> tags have to contain absolute URLs.
So how do you generate absolute URLs? ASP.NET MVC includes built-in functionality for this, though not in a very intuitive way.
There are several overloads of the UrlHelper.Action() method that enable you to pass additional parameters like route values, the protocol to use, and the host name for the URL. If you are using any overload that allows you to specify the protocol, the generated URL will be absolute. So the following code can be used to generate an absolute URL for the About action method of the HomeController:
@Url.Action("About", "Home", null, "http")
Since there are no route values to pass in this case, the third parameter is null. Given that your application is hosted on www.example.com, the method call above will return http://www.example.com/Home/About.
Although you can use the overload of UrlHelper.Action() as described above, I recommend writing a custom UrlHelper extension method for the sake of readability:
/// <summary>
/// Generates a fully qualified URL to an action method by using
/// the specified action name, controller name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="actionName">The name of the action method.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteAction(
this UrlHelper url,
string actionName,
string controllerName,
object routeValues = null
)
{
var httpContext = url.RequestContext.HttpContext;
string scheme = httpContext.Request.Url.Scheme;
return url.Action(
actionName,
controllerName,
routeValues,
scheme
);
}
The UrlHelper.AbsoluteAction() extension method lets you build an absolute URL with a clean and straightforward method call that contains no redundancies (like the protocol) or null parameter values (like the route values):
@Url.AbsoluteAction("About", "Home")
If you are using a different protocol such as https, you can change the protocol constant within UrlHelper.AbsoluteAction() or, if you are using multiple protocols in the same application, introduce either a new method overload or an optional parameter.
I have modified my code sample above following Andrew's suggestion below. Instead of hard-coding "http" as the scheme to use, the sample now shows how to read and use the value of the current request's scheme. This way, the method does not have to be modified when a scheme other than "http" is used. Thanks, Andrew!
