In MVC 5, I had the following extension methods to generate absolute URLs, instead of relative ones:
public static class UrlHelperExtensions { public static string AbsoluteAction( this UrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = url.RequestContext.HttpContext.Request.Url.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); } public static string AbsoluteContent( this UrlHelper url, string contentPath) { return new Uri(url.RequestContext.HttpContext.Request.Url, url.Content(contentPath)).ToString(); } public static string AbsoluteRouteUrl( this UrlHelper url, string routeName, object routeValues = null) { string scheme = url.RequestContext.HttpContext.Request.Url.Scheme; return url.RouteUrl(routeName, routeValues, scheme); } }
What would the equivalent be in ASP.NET Core?
UrlHelper.RequestContext
no longer exists.HttpContext
as there is no longer a static HttpContext.Current
property.As far as I can see, you would now require the HttpContext
or HttpRequest
objects to be passed in also. Am I right? Is there some way to get hold of the current request?
Am I even on the right track, should the domain now be an environment variable, which is simple appended to the relative URL? Would this be a better approach?
IHttpContextAccessor. HttpContext may be null if accessed outside of the request flow. To access information from HttpContext outside the request flow, copy the information inside the request flow.
RouteUrl(String, Object) Generates a fully qualified URL for the specified route values by using a route name. RouteUrl(String, RouteValueDictionary) Generates a fully qualified URL for the specified route values by using a route name.
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:
Microsoft.AspNet.Http.Extensions
. 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. 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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With