Acessar HttpContext
no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
HttpContext encapsula todas as informações específicas sobre uma solicitação e uma resposta HTTP específicas. Uma instância HttpContext
é inicializada quando uma solicitação HTTP é recebida. A instância HttpContext
pode ser acessada por middleware e estruturas como controladores de API Web, Razor Pages, SignalR, gRPC e muito mais.
Para obter informações sobre como usar HttpContext
com uma solicitação e resposta HTTP, consulte Usar HttpContext no ASP.NET Core.
Acessar HttpContext
do Razor Pages
O Razor Pages PageModel expõe a propriedade PageModel.HttpContext:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
A mesma propriedade pode ser usada no Modo de Exibição de Página correspondente de Razor:
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Acessar HttpContext
de um modo de exibição Razor no MVC
Razor exibições no padrão MVC expõem o HttpContext
por meio da propriedade RazorPage.Context na exibição. O exemplo a seguir recupera o nome de usuário atual em um aplicativo de Intranet usando a Autenticação do Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Acessar HttpContext
a partir de um controlador
Os controladores expõem a propriedade ControllerBase.HttpContext:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Acessar HttpContext
de APIs mínimas
Para usar HttpContext
a partir de APIs mínimas, adicione um parâmetro HttpContext
:
app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));
Acessar HttpContext
do middleware
Para usar HttpContext
a partir de componentes de middleware personalizados, use o parâmetro HttpContext
passado para o método Invoke
ou InvokeAsync
:
public class MyCustomMiddleware
{
// ...
public async Task InvokeAsync(HttpContext context)
{
// ...
}
}
Acessar HttpContext
a partir de SignalR
Para usar HttpContext
a partir de SignalR, chame o método GetHttpContext em Hub.Context:
public class MyHub : Hub
{
public async Task SendMessage()
{
var httpContext = Context.GetHttpContext();
// ...
}
}
Acessar HttpContext
a partir de métodos gRPC
Para usar HttpContext
a partir de métodos gRPC, consulte Resolver HttpContext
em métodos gRPC.
Acessar HttpContext
a partir de componentes personalizados
Para outras estruturas e componentes personalizados que exigem acesso ao HttpContext
, a abordagem recomendada é registrar uma dependência usando o contêiner integrado de DI (injeção de dependência). O contêiner de DI fornece o IHttpContextAccessor
para todas as classes que o declaram como uma dependência em seus construtores.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();
No exemplo a seguir:
- o
UserRepository
declara sua dependência noIHttpContextAccessor
. - A dependência é fornecida quando a injeção de dependência resolve a cadeia de dependências e cria uma instância do
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;
// ...
}
}
HttpContext
acesso de um thread em segundo plano
HttpContext
não é thread-safe. Ler ou gravar propriedades de HttpContext
fora do processamento de uma solicitação pode resultar em um NullReferenceException.
Observação
Se seu aplicativo gera erros NullReferenceException
esporádicos, revise as partes do código que iniciam o processamento em segundo plano ou que continuam o processamento depois que uma solicitação é concluída. Procure por erros como a definição de um método controlador como async void
.
Para executar com segurança o trabalho em segundo plano com os dados de HttpContext
:
- Copie os dados necessários durante o processamento da solicitação.
- Passe os dados copiados para uma tarefa em segundo plano.
- Não referencie dados
HttpContext
em tarefas paralelas. Extraia os dados necessários do contexto antes de iniciar as tarefas paralelas.
Para evitar o código não seguro, nunca passe o HttpContext
para um método que realiza o trabalho em segundo plano. Em vez disso, passe os dados necessários. Em vez disso, passe os dados necessários. No exemplo a seguir, SendEmail
chama SendEmailCoreAsync
para começar a enviar um email. O valor do cabeçalho de X-Correlation-Id
é passado para SendEmailCoreAsync
em vez de HttpContext
. A execução do código não aguarda a conclusão de 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
em componentes Razor (Blazor)
IHttpContextAccessor deve ser evitado com a renderização interativa porque não há um HttpContext
disponível válido.
IHttpContextAccessor pode ser usado para componentes que são renderizados estaticamente no servidor. No entanto, recomendamos evitá-lo, se possível.
HttpContext pode ser usado como um parâmetro em cascata apenas em componentes raiz renderizados estaticamente para tarefas gerais, como inspecionar e modificar cabeçalhos ou outras propriedades no componente App
(Components/App.razor
). O valor é sempre null
para renderização interativa.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Para cenários em que o componente HttpContext é necessário em componentes interativos, recomendamos fluir os dados por meio do estado de componente persistente do servidor. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Não use IHttpContextAccessor/HttpContext direta ou indiretamente nos componentes Razor dos aplicativos Blazor do lado do servidor. Os aplicativos Blazor são executados fora do contexto do pipeline ASP.NET Core. Não há garantia de que o HttpContext esteja disponível no IHttpContextAccessor e não há garantia de que o HttpContext mantenha o contexto que iniciou o aplicativo Blazor.
A abordagem recomendada para passar o estado da solicitação para o aplicativo Blazor é por meio de parâmetros de componente raiz durante a renderização inicial do aplicativo. Como alternativa, o aplicativo pode copiar os dados para um serviço com escopo no evento de ciclo de vida de inicialização do componente raiz para uso em todo o aplicativo. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Um aspecto crítico da segurança do lado do servidor Blazor é que o usuário anexado a um determinado circuito pode ser atualizado em algum momento após o circuito Blazor ser estabelecido, mas o IHttpContextAccessor não é atualizado. Para obter mais informações sobre como lidar com essa situação usando serviços personalizados, confira Outros cenários de segurança do ASP.NET Core Blazor do servidor.
HttpContext encapsula todas as informações específicas sobre uma solicitação e uma resposta HTTP específicas. Uma instância HttpContext
é inicializada quando uma solicitação HTTP é recebida. A instância HttpContext
pode ser acessada por middleware e estruturas como controladores de API Web, Razor Pages, SignalR, gRPC e muito mais.
Para obter informações sobre como usar HttpContext
com uma solicitação e resposta HTTP, consulte Usar HttpContext no ASP.NET Core.
Acessar HttpContext
do Razor Pages
O Razor Pages PageModel expõe a propriedade PageModel.HttpContext:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
A mesma propriedade pode ser usada no Modo de Exibição de Página correspondente de Razor:
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Acessar HttpContext
de um modo de exibição Razor no MVC
Razor exibições no padrão MVC expõem o HttpContext
por meio da propriedade RazorPage.Context na exibição. O exemplo a seguir recupera o nome de usuário atual em um aplicativo de Intranet usando a Autenticação do Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Acessar HttpContext
a partir de um controlador
Os controladores expõem a propriedade ControllerBase.HttpContext:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Acessar HttpContext
do middleware
Ao trabalhar com componentes de middleware personalizados, HttpContext
é passado para o método Invoke
ou InvokeAsync
:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
// ...
}
}
Acessar HttpContext
a partir de componentes personalizados
Para outras estruturas e componentes personalizados que exigem acesso ao HttpContext
, a abordagem recomendada é registrar uma dependência usando o contêiner integrado de DI (injeção de dependência). O contêiner de DI fornece o IHttpContextAccessor
para todas as classes que o declaram como uma dependência em seus construtores.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
No exemplo a seguir:
- o
UserRepository
declara sua dependência noIHttpContextAccessor
. - A dependência é fornecida quando a injeção de dependência resolve a cadeia de dependências e cria uma instância do
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);
}
}
HttpContext
acesso de um thread em segundo plano
HttpContext
não é thread-safe. Ler ou gravar propriedades de HttpContext
fora do processamento de uma solicitação pode resultar em um NullReferenceException.
Observação
Se seu aplicativo gera erros NullReferenceException
esporádicos, revise as partes do código que iniciam o processamento em segundo plano ou que continuam o processamento depois que uma solicitação é concluída. Procure por erros como a definição de um método controlador como async void
.
Para executar com segurança o trabalho em segundo plano com os dados de HttpContext
:
- Copie os dados necessários durante o processamento da solicitação.
- Passe os dados copiados para uma tarefa em segundo plano.
- Não referencie dados
HttpContext
em tarefas paralelas. Extraia os dados necessários do contexto antes de iniciar as tarefas paralelas.
Para evitar o código não seguro, nunca passe o HttpContext
para um método que realiza o trabalho em segundo plano. Em vez disso, passe os dados necessários. No exemplo a seguir, SendEmailCore
é chamado para começar a enviar um email. O correlationId
é passado para SendEmailCore
, não para HttpContext
. A execução do código não aguarda a conclusão de 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
em componentes Razor (Blazor)
IHttpContextAccessor deve ser evitado com a renderização interativa porque não há um HttpContext
disponível válido.
IHttpContextAccessor pode ser usado para componentes que são renderizados estaticamente no servidor. No entanto, recomendamos evitá-lo, se possível.
HttpContext pode ser usado como um parâmetro em cascata apenas em componentes raiz renderizados estaticamente para tarefas gerais, como inspecionar e modificar cabeçalhos ou outras propriedades no componente App
(Components/App.razor
). O valor é sempre null
para renderização interativa.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Para cenários em que o componente HttpContext é necessário em componentes interativos, recomendamos fluir os dados por meio do estado de componente persistente do servidor. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Não use IHttpContextAccessor/HttpContext direta ou indiretamente nos componentes Razor dos aplicativos Blazor do lado do servidor. Os aplicativos Blazor são executados fora do contexto do pipeline ASP.NET Core. Não há garantia de que o HttpContext esteja disponível no IHttpContextAccessor e não há garantia de que o HttpContext mantenha o contexto que iniciou o aplicativo Blazor.
A abordagem recomendada para passar o estado da solicitação para o aplicativo Blazor é por meio de parâmetros de componente raiz durante a renderização inicial do aplicativo. Como alternativa, o aplicativo pode copiar os dados para um serviço com escopo no evento de ciclo de vida de inicialização do componente raiz para uso em todo o aplicativo. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Um aspecto crítico da segurança do lado do servidor Blazor é que o usuário anexado a um determinado circuito pode ser atualizado em algum momento após o circuito Blazor ser estabelecido, mas o IHttpContextAccessor não é atualizado. Para obter mais informações sobre como lidar com essa situação usando serviços personalizados, confira Outros cenários de segurança do ASP.NET Core Blazor do servidor.