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.

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;
    }
}

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.

public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc()
         .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
     services.AddHttpContextAccessor();
     services.AddTransient<IUserRepository, UserRepository>();
}
public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc();
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
     services.AddTransient<IUserRepository, UserRepository>();
}

In the following example:

  • UserRepository declares its dependency on IHttpContextAccessor.
  • 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 a NullReferenceException. If your app generates sporadic NullReferenceExceptions , 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 as async 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
    }
}