AspNetCore.Docs/aspnetcore/fundamentals/http-context.md

160 lines
5.1 KiB
Markdown

---
title: Access HttpContext in ASP.NET Core
author: coderandhiker
description: Learn how to access HttpContext in ASP.NET Core.
ms.author: riande
ms.custom: mvc
ms.date: 07/27/2018
uid: fundamentals/httpcontext
---
# Access HttpContext in ASP.NET Core
ASP.NET Core apps access the `HttpContext` through the [IHttpContextAccessor](/dotnet/api/microsoft.aspnetcore.http.ihttpcontextaccessor) interface and its default implementation [HttpContextAccessor](/dotnet/api/microsoft.aspnetcore.http.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](/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pagemodel) exposes the [HttpContext](/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pagemodel.httpcontext) property:
```csharp
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](/dotnet/api/microsoft.aspnetcore.mvc.razor.razorpage.context#Microsoft_AspNetCore_Mvc_Razor_RazorPage_Context) property on the view. The following example retrieves the current username in an Intranet app using Windows Authentication:
```cshtml
@{
var username = Context.User.Identity.Name;
}
```
## Use HttpContext from a controller
Controllers expose the [ControllerBase.HttpContext](/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.httpcontext) property:
```csharp
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:
```csharp
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](xref:fundamentals/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"
```csharp
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"
```csharp
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 on `IHttpContextAccessor`.
* The dependency is supplied when dependency injection resolves the dependency chain and creates an instance of `UserRepository`.
```csharp
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 `NullReferenceException`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 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.
```csharp
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
}
}