Solución:
Después de RC2 y 1.0 ya no es necesario inyectar un IHttpContextAccessor
a su clase de extensión. Está disponible de inmediato en el IUrlHelper
a través de urlhelper.ActionContext.HttpContext.Request
. Luego, crearía una clase de extensión siguiendo la misma idea, pero más simple ya que no habrá ninguna inyección involucrada.
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);
}
Dejando los detalles de cómo construirlo inyectando el accesor en caso de que le sean de utilidad a alguien. También puede estar interesado en la URL absoluta de la solicitud actual, en cuyo caso eche un vistazo al final de la respuesta.
Puede modificar su clase de extensión para usar la IHttpContextAccessor
interfaz para obtener el HttpContext
. Una vez que tenga el contexto, puede obtener el HttpRequest
instancia de HttpContext.Request
y usa sus propiedades Scheme
, Host
, Protocol
etc como en:
string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
Por ejemplo, podría requerir que su clase esté configurada con un 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);
}
....
}
Que es algo que puedes hacer en tu Startup
clase (archivo Startup.cs):
public void Configure(IApplicationBuilder app)
{
...
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
UrlHelperExtensions.Configure(httpContextAccessor);
...
}
Probablemente se le ocurran diferentes formas de obtener el IHttpContextAccessor
en su clase de extensión, pero si desea mantener sus métodos como métodos de extensión al final, deberá inyectar el IHttpContextAccessor
en su clase estática. (De lo contrario, necesitará el IHttpContext
como argumento en cada llamada)
Recién obteniendo la Uri absoluta de la solicitud actual
Si solo desea obtener el uri absoluto de la solicitud actual, puede usar los métodos de extensión GetDisplayUrl
o GetEncodedUrl
desde el UriHelper
clase. (Que es diferente de la UrLAyudante)
GetDisplayUrl. Devuelve los componentes combinados de la URL de la solicitud en un formato sin escape (excepto para QueryString) adecuado solo para visualización. Este formato no debe usarse en encabezados HTTP u otras operaciones HTTP.
GetEncodedUrl. Devuelve los componentes combinados de la URL de la solicitud en un formato de escape completo adecuado para su uso en encabezados HTTP y otras operaciones HTTP.
Para utilizarlos:
- Incluir el espacio de nombres
Microsoft.AspNet.Http.Extensions
. - Consigue el
HttpContext
ejemplo. Ya está disponible en algunas clases (como las vistas de maquinilla de afeitar), pero en otras es posible que deba inyectar unIHttpContextAccessor
como se explicó anteriormente. - Entonces utilícelos como en
this.Context.Request.GetDisplayUrl()
Una alternativa a esos métodos sería crear manualmente el uri absoluto utilizando los valores en el HttpContext.Request
objeto (similar a lo que hace RequireHttpsAttribute):
var absoluteUri = string.Concat(
request.Scheme,
"://",
request.Host.ToUriComponent(),
request.PathBase.ToUriComponent(),
request.Path.ToUriComponent(),
request.QueryString.ToUriComponent());
Para ASP.NET Core 1.0 en adelante
/// <summary>
/// <see cref="IUrlHelper"/> extension methods.
/// </summary>
public static class UrlHelperExtensions
{
/// <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 IUrlHelper url,
string actionName,
string controllerName,
object routeValues = null)
{
return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
}
/// <summary>
/// Generates a fully qualified URL to the specified content by using the specified content path. Converts a
/// virtual (relative) path to an application absolute path.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="contentPath">The content path.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteContent(
this IUrlHelper url,
string contentPath)
{
HttpRequest request = url.ActionContext.HttpContext.Request;
return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString();
}
/// <summary>
/// Generates a fully qualified URL to the specified route by using the route name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="routeName">Name of the route.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteRouteUrl(
this IUrlHelper url,
string routeName,
object routeValues = null)
{
return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
}
}
Consejo de bonificación
No puede registrar directamente un IUrlHelper
en el contenedor DI. Resolviendo una instancia de IUrlHelper
requiere que uses el IUrlHelperFactory
y IActionContextAccessor
. Sin embargo, puede hacer lo siguiente como atajo:
services
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddScoped<IUrlHelper>(x => x
.GetRequiredService<IUrlHelperFactory>()
.GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));
Registro de trabajos pendientes de ASP.NET Core
ACTUALIZAR: Esto no hará que ASP.NET Core 5
Hay indicios de que podrá utilizar LinkGenerator
para crear URL absolutas sin la necesidad de proporcionar una HttpContext
(Este fue el mayor inconveniente de LinkGenerator
y por qué IUrlHelper
aunque más complejo de configurar usando la solución a continuación, fue más fácil de usar) Consulte “Facilite la configuración de un host / esquema para URL absolutas con LinkGenerator”.
No es necesario crear un método de extensión para esto
@Url.Action("Action", "Controller", values: null);
-
Action
– Nombre de la acción -
Controller
– Nombre del responsable del tratamiento -
values
– Objeto que contiene valores de ruta: también conocidos como parámetros GET
También hay muchas otras sobrecargas que Url.Action
que puede utilizar para generar enlaces.