Access HttpContext
in ASP.NET Core
Note
This isn't the latest version of this article. For the current release, see the .NET 8 version of this article.
Warning
This version of ASP.NET Core is no longer supported. For more information, see .NET and .NET Core Support Policy. For the current release, see the .NET 8 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 8 version of this article.
HttpContext encapsulates all information about an individual HTTP request and response. An HttpContext
instance is initialized when an HTTP request is received. The HttpContext
instance is accessible by middleware and app frameworks such as Web API controllers, Razor Pages, SignalR, gRPC, and more.
For information about using HttpContext
with a HTTP request and response, see Use HttpContext in ASP.NET Core.
Access HttpContext
from Razor Pages
The Razor Pages PageModel exposes the PageModel.HttpContext property:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
The same property can be used in the corresponding Razor Page View:
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Access HttpContext
from a Razor view in MVC
Razor views in the MVC pattern expose the HttpContext
via the RazorPage.Context property on the view. The following example retrieves the current username in an intranet app using Windows Authentication:
@{
var username = Context.User.Identity.Name;
// ...
}
Access HttpContext
from a controller
Controllers expose the ControllerBase.HttpContext property:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Access HttpContext
from minimal APIs
To use HttpContext
from minimal APIs, add a HttpContext
parameter:
app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));
Access HttpContext
from middleware
To use HttpContext
from custom middleware components, use the HttpContext
parameter passed into the Invoke
or InvokeAsync
method:
public class MyCustomMiddleware
{
// ...
public async Task InvokeAsync(HttpContext context)
{
// ...
}
}
Access HttpContext
from SignalR
To use HttpContext
from SignalR, call the GetHttpContext method on Hub.Context:
public class MyHub : Hub
{
public async Task SendMessage()
{
var httpContext = Context.GetHttpContext();
// ...
}
}
Access HttpContext
from gRPC methods
To use HttpContext
from gRPC methods, see Resolve HttpContext
in gRPC methods.
Access HttpContext
from custom components
For other framework and custom components that require access to HttpContext
, the recommended approach is to register a dependency using the built-in Dependency Injection (DI) container. The DI container supplies the IHttpContextAccessor
to any classes that declare it as a dependency in their constructors:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();
In the following example:
UserRepository
declares its dependency onIHttpContextAccessor
.- The dependency is supplied when DI resolves the dependency chain and creates an instance of
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
access from a background thread
HttpContext
isn't thread-safe. Reading or writing properties of the HttpContext
outside of processing a request can result in a NullReferenceException.
Note
If your app generates sporadic NullReferenceException
errors, review parts of the code that start background processing or that continue processing after a request completes. Look for mistakes, such as defining a controller method as async void
.
To safely do background work with HttpContext
data:
- Copy the required data during request processing.
- Pass the copied data to a background task.
- Do not reference
HttpContext
data in parallel tasks. Extract the data needed from the context before starting the parallel tasks.
To avoid unsafe code, never pass HttpContext
into a method that does background work. Pass the required data instead. In the following example, SendEmail
calls SendEmailCoreAsync
to start sending an email. The value of the X-Correlation-Id
header is passed to SendEmailCoreAsync
instead of the HttpContext
. Code execution doesn't wait for SendEmailCoreAsync
to complete:
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
in Razor components (Blazor)
IHttpContextAccessor must be avoided with interactive rendering because there isn't a valid HttpContext
available.
IHttpContextAccessor can be used for components that are statically rendered on the server. However, we recommend avoiding it if possible.
HttpContext can be used as a cascading parameter only in statically-rendered root components for general tasks, such as inspecting and modifying headers or other properties in the App
component (Components/App.razor
). The value is always null
for interactive rendering.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
For scenarios where the HttpContext is required in interactive components, we recommend flowing the data via persistent component state from the server. For more information, see Server-side ASP.NET Core Blazor additional security scenarios.
Don't use IHttpContextAccessor/HttpContext directly or indirectly in the Razor components of server-side Blazor apps. Blazor apps run outside of the ASP.NET Core pipeline context. The HttpContext isn't guaranteed to be available within the IHttpContextAccessor, and HttpContext isn't guaranteed to hold the context that started the Blazor app.
The recommended approach for passing request state to the Blazor app is through root component parameters during the app's initial rendering. Alternatively, the app can copy the data into a scoped service in the root component's initialization lifecycle event for use across the app. For more information, see Server-side ASP.NET Core Blazor additional security scenarios.
A critical aspect of server-side Blazor security is that the user attached to a given circuit might become updated at some point after the Blazor circuit is established but the IHttpContextAccessor isn't updated. For more information on addressing this situation with custom services, see Server-side ASP.NET Core Blazor additional security scenarios.
HttpContext encapsulates all information about an individual HTTP request and response. An HttpContext
instance is initialized when an HTTP request is received. The HttpContext
instance is accessible by middleware and app frameworks such as Web API controllers, Razor Pages, SignalR, gRPC, and more.
For information about using HttpContext
with a HTTP request and response, see Use HttpContext in ASP.NET Core.
Access HttpContext
from Razor Pages
The Razor Pages PageModel exposes the PageModel.HttpContext property:
public class IndexModel : PageModel
{
public void OnGet()
{
var message = HttpContext.Request.PathBase;
// ...
}
}
The same property can be used in the corresponding Razor Page View:
@page
@model IndexModel
@{
var message = HttpContext.Request.PathBase;
// ...
}
Access HttpContext
from a Razor view in MVC
Razor views in the MVC pattern expose the HttpContext
via the RazorPage.Context property on the view. The following example retrieves the current username in an intranet app using Windows Authentication:
@{
var username = Context.User.Identity.Name;
// ...
}
Access HttpContext
from a controller
Controllers expose the ControllerBase.HttpContext property:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
// ...
return View();
}
}
Access HttpContext
from middleware
When working with custom middleware components, HttpContext
is passed into the Invoke
or InvokeAsync
method:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
// ...
}
}
Access HttpContext
from custom components
For other framework and custom components that require access to HttpContext
, the recommended approach is to register a dependency using the built-in Dependency Injection (DI) container. The DI container supplies the IHttpContextAccessor
to any classes that declare it as a dependency in their constructors:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
In the following example:
UserRepository
declares its dependency onIHttpContextAccessor
.- The dependency is supplied when DI resolves the dependency chain and creates an instance of
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
access from a background thread
HttpContext
isn't thread-safe. Reading or writing properties of the HttpContext
outside of processing a request can result in a NullReferenceException.
Note
If your app generates sporadic NullReferenceException
errors, review parts of the code that start background processing or that continue processing after a request completes. Look for mistakes, such as defining a controller method as async void
.
To safely do background work with HttpContext
data:
- Copy the required data during request processing.
- Pass the copied data to a background task.
- Do not reference
HttpContext
data in parallel tasks. Extract the data needed from the context before starting the parallel tasks.
To avoid unsafe code, never pass the HttpContext
into a method that does background work. Pass the required data instead. In the following example, SendEmailCore
is called to start sending an email. The correlationId
is passed to SendEmailCore
, not the HttpContext
. Code execution doesn't wait for SendEmailCore
to complete:
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
in Razor components (Blazor)
IHttpContextAccessor must be avoided with interactive rendering because there isn't a valid HttpContext
available.
IHttpContextAccessor can be used for components that are statically rendered on the server. However, we recommend avoiding it if possible.
HttpContext can be used as a cascading parameter only in statically-rendered root components for general tasks, such as inspecting and modifying headers or other properties in the App
component (Components/App.razor
). The value is always null
for interactive rendering.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
For scenarios where the HttpContext is required in interactive components, we recommend flowing the data via persistent component state from the server. For more information, see Server-side ASP.NET Core Blazor additional security scenarios.
Don't use IHttpContextAccessor/HttpContext directly or indirectly in the Razor components of server-side Blazor apps. Blazor apps run outside of the ASP.NET Core pipeline context. The HttpContext isn't guaranteed to be available within the IHttpContextAccessor, and HttpContext isn't guaranteed to hold the context that started the Blazor app.
The recommended approach for passing request state to the Blazor app is through root component parameters during the app's initial rendering. Alternatively, the app can copy the data into a scoped service in the root component's initialization lifecycle event for use across the app. For more information, see Server-side ASP.NET Core Blazor additional security scenarios.
A critical aspect of server-side Blazor security is that the user attached to a given circuit might become updated at some point after the Blazor circuit is established but the IHttpContextAccessor isn't updated. For more information on addressing this situation with custom services, see Server-side ASP.NET Core Blazor additional security scenarios.