Getting absolute URLs using ASP.NET Core

After RC2 and 1.0 you no longer need to inject an IHttpContextAccessor to you extension class. It is immediately available in the IUrlHelper through the urlhelper.ActionContext.HttpContext.Request. You would then create an extension class following the same idea, but simpler since there will be no injection involved.

public static string AbsoluteAction(
    this IUrlHelper url,
    string actionName, 
    string controllerName, 
    object routeValues = null)
{
    string scheme = url.ActionContext.HttpContext.Request.Scheme;
    return url.Action(actionName, controllerName, routeValues, scheme);
}

Leaving the details on how to build it injecting the accesor in case they are useful to someone. You might also just be interested in the absolute url of the current request, in which case take a look at the end of the answer.


You could modify your extension class to use the IHttpContextAccessor interface to get the HttpContext. Once you have the context, then you can get the HttpRequest instance from HttpContext.Request and use its properties Scheme, Host, Protocol etc as in:

string scheme = HttpContextAccessor.HttpContext.Request.Scheme;

For example, you could require your class to be configured with an HttpContextAccessor:

public static class UrlHelperExtensions
{        
    private static IHttpContextAccessor HttpContextAccessor;
    public static void Configure(IHttpContextAccessor httpContextAccessor)
    {           
        HttpContextAccessor = httpContextAccessor;  
    }

    public static string AbsoluteAction(
        this IUrlHelper url,
        string actionName, 
        string controllerName, 
        object routeValues = null)
    {
        string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
        return url.Action(actionName, controllerName, routeValues, scheme);
    }

    ....
}

Which is something you can do on your Startup class (Startup.cs file):

public void Configure(IApplicationBuilder app)
{
    ...

    var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
    UrlHelperExtensions.Configure(httpContextAccessor);

    ...
}

You could probably come up with different ways of getting the IHttpContextAccessor in your extension class, but if you want to keep your methods as extension methods in the end you will need to inject the IHttpContextAccessor into your static class. (Otherwise you will need the IHttpContext as an argument on each call)


Just getting the absoluteUri of the current request

If you just want to get the absolute uri of the current request, you can use the extension methods GetDisplayUrl or GetEncodedUrl from the UriHelper class. (Which is different from the UrLHelper)

GetDisplayUrl. Returns the combined components of the request URL in a fully un-escaped form (except for the QueryString) suitable only
for display. This format should not be used in HTTP headers or other
HTTP operations.

GetEncodedUrl. Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers and other
HTTP operations.

In order to use them:

  • Include the namespace Microsoft.AspNet.Http.Extensions.
  • Get the HttpContext instance. It is already available in some classes (like razor views), but in others you might need to inject an IHttpContextAccessor as explained above.
  • Then just use them as in this.Context.Request.GetDisplayUrl()

An alternative to those methods would be manually crafting yourself the absolute uri using the values in the HttpContext.Request object (Similar to what the RequireHttpsAttribute does):

var absoluteUri = string.Concat(
                        request.Scheme,
                        "://",
                        request.Host.ToUriComponent(),
                        request.PathBase.ToUriComponent(),
                        request.Path.ToUriComponent(),
                        request.QueryString.ToUriComponent());

Leave a Comment