Acceso a HttpContext
en ASP.NET Core
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulte la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión .NET 8 de este artículo.
HttpContext encapsula toda la información sobre una solicitud y una respuesta HTTP individual. Una instancia de HttpContext
se inicializa cuando se recibe una solicitud HTTP. Se puede acceder a la instancia de HttpContext
mediante middleware y marcos de aplicaciones, como controladores de API web, Razor Pages, SignalR, gRPC, etc.
Para obtener información sobre el uso de HttpContext
con una solicitud y respuesta HTTP, consulte Uso de HttpContext en ASP.NET Core.
Acceso a HttpContext
desde Razor Pages
PageModel de Razor Pages expone la propiedad PageModel.HttpContext:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
Se puede usar la misma propiedad en la vista de Razor Pages correspondiente.
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Acceso a HttpContext
desde una vista de Razor en MVC
Las vistas Razor del patrón de MVC exponen el objeto HttpContext
mediante la propiedad RazorPage.Context en la vista. En el ejemplo siguiente se recupera el nombre de usuario actual de una aplicación de intranet mediante Autenticación de Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Acceso a HttpContext
desde un controlador
Los controladores exponen la propiedad ControllerBase.HttpContext:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Acceso a HttpContext
desde API mínimas
Para usar HttpContext
desde API mínimas, agregue un parámetro HttpContext
:
app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));
Acceso a HttpContext
desde middleware
Para usar HttpContext
desde componentes de middleware personalizados, use el parámetro HttpContext
pasado al método Invoke
o InvokeAsync
:
public class MyCustomMiddleware
{
// ...
public async Task InvokeAsync(HttpContext context)
{
// ...
}
}
Acceso a HttpContext
desde SignalR
Para usar HttpContext
desde SignalR, llame al método GetHttpContext en Hub.Context:
public class MyHub : Hub
{
public async Task SendMessage()
{
var httpContext = Context.GetHttpContext();
// ...
}
}
Acceso a HttpContext
desde los métodos de gRPC
Para usar HttpContext
desde los métodos de gRPC, consulteResolución HttpContext
en métodos de gRPC.
Acceso a HttpContext
desde componentes personalizados
Para los componentes de otro marco y componentes personalizados que requieren acceso a HttpContext
, el enfoque recomendado es registrar una dependencia mediante el contenedor integrado de inserción de dependencias (DI). El contenedor de DI proporciona IHttpContextAccessor
a cualquier clase que la declare como una dependencia en sus constructores:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();
En el ejemplo siguiente:
UserRepository
declara su dependencia deIHttpContextAccessor
.- La dependencia se proporciona cuando DI resuelve la cadena de dependencias y crea una instancia de
UserRepository
.
public class UserRepository : IUserRepository
{
private readonly IHttpContextAccessor _httpContextAccessor;
public UserRepository(IHttpContextAccessor httpContextAccessor) =>
_httpContextAccessor = httpContextAccessor;
public void LogCurrentUser()
{
var username = _httpContextAccessor.HttpContext.User.Identity.Name;
// ...
}
}
Acceso a HttpContext
desde un subproceso en segundo plano
HttpContext
no es seguro para subprocesos. La lectura o escritura de propiedades de HttpContext
fuera del procesamiento de una solicitud puede iniciar una excepción NullReferenceException.
Nota
Si la aplicación inicia errores NullReferenceException
esporádicos, revise los elementos del código que inician el procesamiento en segundo plano, o bien que lo continúan después de que se complete una solicitud. Busque errores, como la definición de un método de controlador como async void
.
Para realizar el trabajo en segundo plano de forma segura con datos HttpContext
:
- Copie los datos necesarios durante el procesamiento de la solicitud.
- Pase los datos copiados a una tarea en segundo plano.
- No haga referencia a datos de
HttpContext
en tareas paralelas. Extraiga los datos necesarios del contexto antes de iniciar las tareas paralelas.
Para evitar código no seguro, no pase nunca HttpContext
a un método que realice trabajos en segundo plano. En su lugar, pase los datos que necesite. En el ejemplo siguiente, SendEmail
llama a SendEmailCoreAsync
para empezar a enviar un correo electrónico. El valor del encabezado X-Correlation-Id
se pasa a SendEmailCoreAsync
en lugar de a HttpContext
. La ejecución de código no espera a que se complete SendEmailCoreAsync
:
public class EmailController : Controller
{
public IActionResult SendEmail(string email)
{
var correlationId = HttpContext.Request.Headers["X-Correlation-Id"].ToString();
_ = SendEmailCoreAsync(correlationId);
return View();
}
private async Task SendEmailCoreAsync(string correlationId)
{
// ...
}
}
IHttpContextAccessor
/HttpContext
en componentes de Razor (Blazor)
IHttpContextAccessor debe evitarse con la representación interactiva porque no hay un HttpContext
válido disponible.
IHttpContextAccessor se puede usar para los componentes que se representan estáticamente en el servidor. Sin embargo, se recomienda evitarlo si es posible.
HttpContextse puede usar como parámetro en cascada solo en componentes raíz representados estáticamente para tareas generales, como inspeccionar y modificar encabezados u otras propiedades del componente App
(Components/App.razor
). El valor siempre es null
para la representación interactiva.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
En escenarios en los que se requiere el HttpContext en componentes interactivos, se recomienda hacer fluir los datos a través del estado del componente persistente desde el servidor. Para más información, veaOtros escenarios de seguridad de Blazor en ASP.NET Core del lado servidor.
No use IHttpContextAccessor/HttpContext directa o indirectamente en los componentes Razor de las aplicaciones Blazor del lado servidor. Las aplicaciones de Blazor se ejecutan fuera del contexto de la canalización de ASP.NET Core. No se garantiza que HttpContext esté disponible en IHttpContextAccessor, ni tampoco que HttpContext contenga el contexto que ha iniciado la aplicación de Blazor.
El enfoque recomendado para pasar el estado de solicitud a la aplicación de Blazor es a través de parámetros de componente raíz durante la representación inicial de la aplicación. Como alternativa, la aplicación puede copiar los datos en un servicio con ámbito en el evento de ciclo de vida de inicialización del componente raíz para usarlos en toda la aplicación. Para más información, veaOtros escenarios de seguridad de Blazor en ASP.NET Core del lado servidor.
Un aspecto crítico de la seguridad de Blazor en el lado del servidor es que el usuario asociado a un circuito determinado se puede actualizar en algún momento después de que se establezca el circuito de Blazor, pero IHttpContextAccessor no se actualice. Para obtener más información sobre cómo abordar esta situación con servicios personalizados, consulte: ASP.NET Core Blazor en el lado del servidor: escenarios de seguridad adicionales.
HttpContext encapsula toda la información sobre una solicitud y una respuesta HTTP individual. Una instancia de HttpContext
se inicializa cuando se recibe una solicitud HTTP. Se puede acceder a la instancia de HttpContext
mediante middleware y marcos de aplicaciones, como controladores de API web, Razor Pages, SignalR, gRPC, etc.
Para obtener información sobre el uso de HttpContext
con una solicitud y respuesta HTTP, consulte Uso de HttpContext en ASP.NET Core.
Acceso a HttpContext
desde Razor Pages
PageModel de Razor Pages expone la propiedad PageModel.HttpContext:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
Se puede usar la misma propiedad en la vista de Razor Pages correspondiente.
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Acceso a HttpContext
desde una vista de Razor en MVC
Las vistas Razor del patrón de MVC exponen el objeto HttpContext
mediante la propiedad RazorPage.Context en la vista. En el ejemplo siguiente se recupera el nombre de usuario actual de una aplicación de intranet mediante Autenticación de Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Acceso a HttpContext
desde un controlador
Los controladores exponen la propiedad ControllerBase.HttpContext:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Acceso a HttpContext
desde middleware
Cuando se trabaja con componentes de middleware personalizados, HttpContext
se pasa al método Invoke
o InvokeAsync
:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
// ...
}
}
Acceso a HttpContext
desde componentes personalizados
Para los componentes de otro marco y componentes personalizados que requieren acceso a HttpContext
, el enfoque recomendado es registrar una dependencia mediante el contenedor integrado de inserción de dependencias (DI). El contenedor de DI proporciona IHttpContextAccessor
a cualquier clase que la declare como una dependencia en sus constructores:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
En el ejemplo siguiente:
UserRepository
declara su dependencia deIHttpContextAccessor
.- La dependencia se proporciona cuando DI resuelve la cadena de dependencias y crea una instancia de
UserRepository
.
public class UserRepository : IUserRepository
{
private readonly IHttpContextAccessor _httpContextAccessor;
public UserRepository(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void LogCurrentUser()
{
var username = _httpContextAccessor.HttpContext.User.Identity.Name;
service.LogAccessRequest(username);
}
}
Acceso a HttpContext
desde un subproceso en segundo plano
HttpContext
no es seguro para subprocesos. La lectura o escritura de propiedades de HttpContext
fuera del procesamiento de una solicitud puede iniciar una excepción NullReferenceException.
Nota
Si la aplicación inicia errores NullReferenceException
esporádicos, revise los elementos del código que inician el procesamiento en segundo plano, o bien que lo continúan después de que se complete una solicitud. Busque errores, como la definición de un método de controlador como async void
.
Para realizar el trabajo en segundo plano de forma segura con datos HttpContext
:
- Copie los datos necesarios durante el procesamiento de la solicitud.
- Pase los datos copiados a una tarea en segundo plano.
- No haga referencia a datos de
HttpContext
en tareas paralelas. Extraiga los datos necesarios del contexto antes de iniciar las tareas paralelas.
Para evitar código no seguro, no pase nunca HttpContext
a un método que realice trabajos en segundo plano. En su lugar, pase los datos que necesite. En el ejemplo siguiente, se llama a SendEmailCore
para empezar a enviar un correo electrónico. correlationId
se pasa a SendEmailCore
, no a HttpContext
. La ejecución de código no espera a que se complete SendEmailCore
:
public class EmailController : Controller
{
public IActionResult SendEmail(string email)
{
var correlationId = HttpContext.Request.Headers["x-correlation-id"].ToString();
_ = SendEmailCore(correlationId);
return View();
}
private async Task SendEmailCore(string correlationId)
{
// ...
}
}
IHttpContextAccessor
/HttpContext
en componentes de Razor (Blazor)
IHttpContextAccessor debe evitarse con la representación interactiva porque no hay un HttpContext
válido disponible.
IHttpContextAccessor se puede usar para los componentes que se representan estáticamente en el servidor. Sin embargo, se recomienda evitarlo si es posible.
HttpContextse puede usar como parámetro en cascada solo en componentes raíz representados estáticamente para tareas generales, como inspeccionar y modificar encabezados u otras propiedades del componente App
(Components/App.razor
). El valor siempre es null
para la representación interactiva.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
En escenarios en los que se requiere el HttpContext en componentes interactivos, se recomienda hacer fluir los datos a través del estado del componente persistente desde el servidor. Para más información, veaOtros escenarios de seguridad de Blazor en ASP.NET Core del lado servidor.
No use IHttpContextAccessor/HttpContext directa o indirectamente en los componentes Razor de las aplicaciones Blazor del lado servidor. Las aplicaciones de Blazor se ejecutan fuera del contexto de la canalización de ASP.NET Core. No se garantiza que HttpContext esté disponible en IHttpContextAccessor, ni tampoco que HttpContext contenga el contexto que ha iniciado la aplicación de Blazor.
El enfoque recomendado para pasar el estado de solicitud a la aplicación de Blazor es a través de parámetros de componente raíz durante la representación inicial de la aplicación. Como alternativa, la aplicación puede copiar los datos en un servicio con ámbito en el evento de ciclo de vida de inicialización del componente raíz para usarlos en toda la aplicación. Para más información, veaOtros escenarios de seguridad de Blazor en ASP.NET Core del lado servidor.
Un aspecto crítico de la seguridad de Blazor en el lado del servidor es que el usuario asociado a un circuito determinado se puede actualizar en algún momento después de que se establezca el circuito de Blazor, pero IHttpContextAccessor no se actualice. Para obtener más información sobre cómo abordar esta situación con servicios personalizados, consulte: ASP.NET Core Blazor en el lado del servidor: escenarios de seguridad adicionales.