Accesso HttpContext
in ASP.NET Core
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 8 di questo articolo.
HttpContext incapsula tutte le informazioni su una singola richiesta e risposta HTTP. Un'istanza HttpContext
viene inizializzata quando viene ricevuta una richiesta HTTP. L'istanza HttpContext
è accessibile dal middleware e dai framework dell'app, ad esempio controller API Web, Razor Pagine, SignalR, gRPC e altro ancora.
Per informazioni sull'uso HttpContext
con una richiesta e una risposta HTTP, vedere Usare HttpContext in ASP.NET Core.
Accesso HttpContext
da Razor pagine
Pages Razor PageModel espone la PageModel.HttpContext proprietà :
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
La stessa proprietà può essere usata nella visualizzazione pagina corrispondente Razor :
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Accesso HttpContext
da una Razor visualizzazione in MVC
Razor le visualizzazioni nel modello MVC espongono tramite HttpContext
la RazorPage.Context proprietà nella vista. L'esempio seguente recupera il nome utente corrente in un'app Intranet usando l'autenticazione di Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Accesso HttpContext
da un controller
I controller espongono la ControllerBase.HttpContext proprietà :
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Accesso HttpContext
da API minime
Per usare HttpContext
da API minime, aggiungere un HttpContext
parametro:
app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));
Accesso HttpContext
dal middleware
Per usare HttpContext
da componenti middleware personalizzati, usare il HttpContext
parametro passato nel Invoke
metodo o InvokeAsync
:
public class MyCustomMiddleware
{
// ...
public async Task InvokeAsync(HttpContext context)
{
// ...
}
}
Accesso HttpContext
da SignalR
Per usare HttpContext
da SignalR, chiamare il GetHttpContext metodo su Hub.Context:
public class MyHub : Hub
{
public async Task SendMessage()
{
var httpContext = Context.GetHttpContext();
// ...
}
}
Accesso HttpContext
dai metodi gRPC
Per usare HttpContext
i metodi gRPC, vedere Risolvere HttpContext
nei metodi gRPC.
Accesso HttpContext
da componenti personalizzati
Per altri framework e componenti personalizzati che richiedono l'accesso a HttpContext
, l'approccio consigliato consiste nel registrare una dipendenza usando il contenitore di inserimento delle dipendenze predefinito. Il contenitore di inserimento delle dipendenze fornisce a IHttpContextAccessor
tutte le classi che la dichiarano come dipendenza nei relativi costruttori:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();
Nell'esempio seguente :
UserRepository
dichiara la dipendenza daIHttpContextAccessor
.- La dipendenza viene fornita quando l'inserimento delle dipendenze risolve la catena di dipendenze e crea un'istanza di
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
accesso da un thread in background
HttpContext
non è thread-safe. La lettura o scrittura delle proprietà HttpContext
di fuori dell'elaborazione di una richiesta può provocare un'eccezione NullReferenceException.
Nota
Se l'app genera errori sporadici NullReferenceException
, esaminare parti del codice che avviano l'elaborazione in background o che continuano l'elaborazione dopo il completamento di una richiesta. Cercare errori, ad esempio la definizione di un metodo controller come async void
.
Per eseguire in modo sicuro operazioni in background con i HttpContext
dati:
- Copiare i dati necessari durante l'elaborazione della richiesta.
- Passare i dati copiati a un'attività in background.
- Non fare riferimento ai
HttpContext
dati nelle attività parallele. Estrarre i dati necessari dal contesto prima di avviare le attività parallele.
Per evitare codice non sicuro, non passare HttpContext
mai a un metodo che esegue il lavoro in background. Passare invece i dati necessari. Nell'esempio seguente viene SendEmail
chiamato SendEmailCoreAsync
per iniziare a inviare un messaggio di posta elettronica. Il valore dell'intestazione X-Correlation-Id
viene passato a anziché a SendEmailCoreAsync
HttpContext
. L'esecuzione del codice non attende SendEmailCoreAsync
il completamento:
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
nei Razor componenti (Blazor)
IHttpContextAccessor è necessario evitare il rendering interattivo perché non è disponibile un valore valido HttpContext
.
IHttpContextAccessor può essere usato per i componenti di cui viene eseguito il rendering statico nel server. Tuttavia, è consigliabile evitarlo, se possibile.
HttpContext può essere usato come parametro a catena solo nei componenti radice sottoposti a rendering statico per attività generali, ad esempio l'ispezione e la modifica di intestazioni o altre proprietà nel App
componente (Components/App.razor
). Il valore è sempre null
per il rendering interattivo.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Per gli scenari in cui HttpContext è necessario nei componenti interattivi, è consigliabile fluire i dati tramite lo stato del componente persistente dal server. Per altre informazioni, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.
Non usare IHttpContextAccessor/HttpContext direttamente o indirettamente nei Razor componenti delle app lato Blazor server. Blazor le app vengono eseguite all'esterno del contesto della pipeline core ASP.NET. Non HttpContext è garantito che sia disponibile all'interno di IHttpContextAccessore HttpContext non sia garantito che contenga il contesto che ha avviato l'app Blazor .
L'approccio consigliato per passare lo stato della richiesta all'app consiste nell'usare Blazor i parametri del componente radice durante il rendering iniziale dell'app. In alternativa, l'app può copiare i dati in un servizio con ambito nell'evento del ciclo di vita di inizializzazione del componente radice da usare nell'app. Per altre informazioni, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.
Un aspetto critico della sicurezza lato Blazor server è che l'utente collegato a un determinato circuito potrebbe essere aggiornato a un certo punto dopo che il Blazor circuito è stato stabilito, ma IHttpContextAccessornon viene aggiornato. Per altre informazioni sulla gestione di questa situazione con i servizi personalizzati, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.
HttpContext incapsula tutte le informazioni su una singola richiesta e risposta HTTP. Un'istanza HttpContext
viene inizializzata quando viene ricevuta una richiesta HTTP. L'istanza HttpContext
è accessibile dal middleware e dai framework dell'app, ad esempio controller API Web, Razor Pagine, SignalR, gRPC e altro ancora.
Per informazioni sull'uso HttpContext
con una richiesta e una risposta HTTP, vedere Usare HttpContext in ASP.NET Core.
Accesso HttpContext
da Razor pagine
Pages Razor PageModel espone la PageModel.HttpContext proprietà :
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
La stessa proprietà può essere usata nella visualizzazione pagina corrispondente Razor :
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Accesso HttpContext
da una Razor visualizzazione in MVC
Razor le visualizzazioni nel modello MVC espongono tramite HttpContext
la RazorPage.Context proprietà nella vista. L'esempio seguente recupera il nome utente corrente in un'app Intranet usando l'autenticazione di Windows:
@{
var username = Context.User.Identity.Name;
// ...
}
Accesso HttpContext
da un controller
I controller espongono la ControllerBase.HttpContext proprietà :
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Accesso HttpContext
dal middleware
Quando si utilizzano componenti middleware personalizzati, HttpContext
viene passato al Invoke
metodo o InvokeAsync
:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
// ...
}
}
Accesso HttpContext
da componenti personalizzati
Per altri framework e componenti personalizzati che richiedono l'accesso a HttpContext
, l'approccio consigliato consiste nel registrare una dipendenza usando il contenitore di inserimento delle dipendenze predefinito. Il contenitore di inserimento delle dipendenze fornisce a IHttpContextAccessor
tutte le classi che la dichiarano come dipendenza nei relativi costruttori:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
Nell'esempio seguente :
UserRepository
dichiara la dipendenza daIHttpContextAccessor
.- La dipendenza viene fornita quando l'inserimento delle dipendenze risolve la catena di dipendenze e crea un'istanza di
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
accesso da un thread in background
HttpContext
non è thread-safe. La lettura o scrittura delle proprietà HttpContext
di fuori dell'elaborazione di una richiesta può provocare un'eccezione NullReferenceException.
Nota
Se l'app genera errori sporadici NullReferenceException
, esaminare parti del codice che avviano l'elaborazione in background o che continuano l'elaborazione dopo il completamento di una richiesta. Cercare errori, ad esempio la definizione di un metodo controller come async void
.
Per eseguire in modo sicuro operazioni in background con i HttpContext
dati:
- Copiare i dati necessari durante l'elaborazione della richiesta.
- Passare i dati copiati a un'attività in background.
- Non fare riferimento ai
HttpContext
dati nelle attività parallele. Estrarre i dati necessari dal contesto prima di avviare le attività parallele.
Per evitare codice non sicuro, non passare mai l'oggetto HttpContext
in un metodo che esegue il lavoro in background. Passare invece i dati necessari. Nell'esempio SendEmailCore
seguente viene chiamato per iniziare a inviare un messaggio di posta elettronica. L'oggetto correlationId
viene passato a , non all'oggetto SendEmailCore
HttpContext
. L'esecuzione del codice non attende SendEmailCore
il completamento:
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
nei Razor componenti (Blazor)
IHttpContextAccessor è necessario evitare il rendering interattivo perché non è disponibile un valore valido HttpContext
.
IHttpContextAccessor può essere usato per i componenti di cui viene eseguito il rendering statico nel server. Tuttavia, è consigliabile evitarlo, se possibile.
HttpContext può essere usato come parametro a catena solo nei componenti radice sottoposti a rendering statico per attività generali, ad esempio l'ispezione e la modifica di intestazioni o altre proprietà nel App
componente (Components/App.razor
). Il valore è sempre null
per il rendering interattivo.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Per gli scenari in cui HttpContext è necessario nei componenti interattivi, è consigliabile fluire i dati tramite lo stato del componente persistente dal server. Per altre informazioni, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.
Non usare IHttpContextAccessor/HttpContext direttamente o indirettamente nei Razor componenti delle app lato Blazor server. Blazor le app vengono eseguite all'esterno del contesto della pipeline core ASP.NET. Non HttpContext è garantito che sia disponibile all'interno di IHttpContextAccessore HttpContext non sia garantito che contenga il contesto che ha avviato l'app Blazor .
L'approccio consigliato per passare lo stato della richiesta all'app consiste nell'usare Blazor i parametri del componente radice durante il rendering iniziale dell'app. In alternativa, l'app può copiare i dati in un servizio con ambito nell'evento del ciclo di vita di inizializzazione del componente radice da usare nell'app. Per altre informazioni, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.
Un aspetto critico della sicurezza lato Blazor server è che l'utente collegato a un determinato circuito potrebbe essere aggiornato a un certo punto dopo che il Blazor circuito è stato stabilito, ma IHttpContextAccessornon viene aggiornato. Per altre informazioni sulla gestione di questa situazione con i servizi personalizzati, vedere Scenari di sicurezza aggiuntivi sul lato server ASP.NET CoreBlazor.