5.1 KiB
title | author | description | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|
Access HttpContext in ASP.NET Core | coderandhiker | Learn how to access HttpContext in ASP.NET Core. | riande | mvc | 07/27/2018 | fundamentals/httpcontext |
Access HttpContext in ASP.NET Core
ASP.NET Core apps access the HttpContext
through the IHttpContextAccessor interface and its default implementation HttpContextAccessor. It's only necessary to use IHttpContextAccessor
when you need access to the HttpContext
inside a service.
::: moniker range=">= aspnetcore-2.0"
Use HttpContext from Razor Pages
The Razor Pages PageModel exposes the HttpContext property:
public class AboutModel : PageModel
{
public string Message { get; set; }
public void OnGet()
{
Message = HttpContext.Request.PathBase;
}
}
::: moniker-end
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;
// Do something with the 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)
{
// Middleware initialization optionally using HttpContext
}
}
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-2.1"
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddHttpContextAccessor();
services.AddTransient<IUserRepository, UserRepository>();
}
::: moniker-end
::: moniker range="<= aspnetcore-2.0"
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
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
is not thread-safe. Reading or writing properties of the HttpContext
outside of processing a request can result in a NullReferenceException
.
[!NOTE] Using
HttpContext
outside of processing a request often results in aNullReferenceException
. If your app generates sporadicNullReferenceException
s , review parts of the code that start background processing, or that continue processing after a request completes. Look for a mistakes like 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 does background work - pass the data you need instead.
public class EmailController
{
public ActionResult SendEmail(string email)
{
var correlationId = HttpContext.Request.Headers["x-correlation-id"].ToString();
// Starts sending an email, but doesn't wait for it to complete
_ = SendEmailCore(correlationId);
return View();
}
private async Task SendEmailCore(string correlationId)
{
// send the email
}
}