5.2 KiB
title | author | description | monikerRange | ms.author | ms.custom | ms.date | no-loc | uid | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Access HttpContext in ASP.NET Core | coderandhiker | Learn how to access HttpContext in ASP.NET Core. | >= aspnetcore-2.1 | riande | mvc | 5/5/2020 |
|
fundamentals/httpcontext |
Access HttpContext in ASP.NET Core
ASP.NET Core apps access HttpContext
through the xref:Microsoft.AspNetCore.Http.IHttpContextAccessor interface and its default implementation xref:Microsoft.AspNetCore.Http.HttpContextAccessor. It's only necessary to use IHttpContextAccessor
when you need access to the HttpContext
inside a service.
Use HttpContext from Razor Pages
The Razor Pages xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel exposes the xref:Microsoft.AspNetCore.Mvc.RazorPages.PageModel.HttpContext property:
public class AboutModel : PageModel
{
public string Message { get; set; }
public void OnGet()
{
Message = HttpContext.Request.PathBase;
}
}
Use HttpContext from a Razor view
Razor views expose the HttpContext
directly via a 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;
...
}
Use HttpContext from a controller
Controllers expose the ControllerBase.HttpContext property:
public class HomeController : Controller
{
public IActionResult About()
{
var pathBase = HttpContext.Request.PathBase;
...
return View();
}
}
Use HttpContext from middleware
When working with custom middleware components, HttpContext
is passed into the Invoke
or InvokeAsync
method and can be accessed when the middleware is configured:
public class MyCustomMiddleware
{
public Task InvokeAsync(HttpContext context)
{
...
}
}
Use 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 container. The dependency injection container supplies the IHttpContextAccessor
to any classes that declare it as a dependency in their constructors:
::: moniker range=">= aspnetcore-3.0"
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
::: moniker-end
::: moniker range="< aspnetcore-3.0"
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
::: moniker-end
In the following example:
UserRepository
declares its dependency onIHttpContextAccessor
.- The dependency is supplied when dependency injection 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 xref:System.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 asasync void
.
To safely perform background work with HttpContext
data:
- Copy the required data during request processing.
- Pass the copied data to a background task.
To avoid unsafe code, never pass the HttpContext
into a method that performs 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)
{
...
}
}