Zugreifen auf HttpContext in ASP.NET Core

HttpContext kapselt sämtliche Informationen zu einer einzelnen HTTP-Anforderung und -Antwort. Eine HttpContext-Instanz wird initialisiert, wenn eine HTTP-Anforderung empfangen wird. Auf die HttpContext-Instanz kann von Middleware und App-Frameworks wie Web-API-Controllern, Razor Pages, SignalR, gRPC und mehr zugegriffen werden.

Informationen zur Verwendung von HttpContext mit einer HTTP-Anforderung und -Antwort finden Sie unter Verwenden von HttpContext in ASP.NET Core.

Zugreifen auf HttpContext aus Razor Pages

Das PageModel von Razor Pages stellt die PageModel.HttpContext-Eigenschaft zur Verfügung:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var message = HttpContext.Request.PathBase;

        // ...
    }
}

Dieselbe Eigenschaft kann in der entsprechenden Razor-Seitenansicht verwendet werden:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Zugreifen auf HttpContext aus einer Razor-Ansicht in MVC

Razor-Ansichten im MVC-Muster machen HttpContext über die RazorPage.Context-Eigenschaft in der Ansicht verfügbar. Im folgenden Beispiel wird der aktuelle Benutzername in einer Intranet-App abgerufen, die die Windows-Authentifizierung verwendet:

@{
    var username = Context.User.Identity.Name;

    // ...
}

Zugreifen auf HttpContext aus einem Controller

Controller machen die ControllerBase.HttpContext-Eigenschaft verfügbar:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var pathBase = HttpContext.Request.PathBase;

        // ...

        return View();
    }
}

Zugreifen auf HttpContext aus minimalen APIs

Um HttpContext aus minimalen APIs zu verwenden, fügen Sie den Parameter HttpContext hinzu:

app.MapGet("/", (HttpContext context) => context.Response.WriteAsync("Hello World"));

Zugreifen auf HttpContext aus Middleware

Um HttpContext aus benutzerdefinierten Middlewarekomponenten nutzen zu können, verwenden Sie den Parameter HttpContext, der an die Methode Invoke oder InvokeAsync übergeben wird:

public class MyCustomMiddleware
{
    // ...

    public async Task InvokeAsync(HttpContext context)
    {
        // ...
    }
}

Zugreifen auf HttpContext aus SignalR

Um HttpContext aus SignalR zu verwenden, rufen Sie die Methode GetHttpContext für Hub.Context auf:

public class MyHub : Hub
{
    public async Task SendMessage()
    {
        var httpContext = Context.GetHttpContext();

        // ...
    }
}

Zugreifen auf HttpContext aus gRPC-Methoden

Informationen zum Verwenden von HttpContext aus gRPC-Methoden finden Sie unter Auflösen von HttpContext in gRPC-Methoden.

Zugreifen auf HttpContext aus benutzerdefinierten Komponenten

Für andere Framework- und benutzerdefinierte Komponenten, die Zugriff auf HttpContext erfordern, wird empfohlen, eine Abhängigkeit mithilfe des integrierten Abhängigkeitsinjektionscontainers zu registrieren. Der Abhängigkeitsinjektionscontainer stellt IHttpContextAccessor allen Klassen zur Verfügung, die ihn in ihren Konstruktoren als Abhängigkeit deklarieren:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();

Im folgenden Beispiel:

  • UserRepository deklariert seine Abhängigkeit von IHttpContextAccessor.
  • Die Abhängigkeit wird bereitgestellt, wenn die Abhängigkeitsinjektion die Abhängigkeitskette auflöst und eine UserRepository-Instanz erstellt.
public class UserRepository : IUserRepository
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserRepository(IHttpContextAccessor httpContextAccessor) =>
        _httpContextAccessor = httpContextAccessor;

    public void LogCurrentUser()
    {
        var username = _httpContextAccessor.HttpContext.User.Identity.Name;

        // ...
    }
}

Zugreifen auf HttpContext aus einem Hintergrundthread

HttpContext ist nicht threadsicher. Eigenschaften von HttpContext außerhalb der Verarbeitung einer Anforderung zu lesen oder zu schreiben kann zu einer NullReferenceException führen.

Hinweis

Wenn Ihre App sporadische NullReferenceException-Fehler erzeugt, überprüfen Sie die Teile des Codes, die die Hintergrundverarbeitung starten oder die Verarbeitung fortsetzen, nachdem eine Anforderung erfüllt wurde. Suchen Sie nach Fehlern, wie das Definieren einer Controllermethode als async void.

So werden Hintergrundaufgaben mit HttpContext-Daten sicher ausgeführt

  • Kopieren Sie die benötigten Daten während der Verarbeitung der Anforderung.
  • Übergeben Sie die kopierten Daten an eine Hintergrundaufgabe.
  • Verweisen Sie in parallelen Aufgaben nicht auf HttpContext-Daten. Extrahieren Sie die erforderlichen Daten aus dem Kontext, bevor Sie die parallelen Aufgaben starten.

Um unsicheren Code zu vermeiden, übergeben Sie HttpContext niemals an eine Methode, die im Hintergrund arbeitet. Übergeben Sie stattdessen die erforderlichen Daten. Im folgenden Beispiel wird SendEmailCoreAsync von SendEmail aufgerufen, um mit dem Senden einer E-Mail zu beginnen. Der Wert des Headers X-Correlation-Id wird an SendEmailCoreAsync statt HttpContext übergeben. Die Codeausführung wartet nicht auf den Abschluss von SendEmailCoreAsync:

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 Komponenten (Blazor)

IHttpContextAccessor muss mit interaktivem Rendering vermieden werden, da kein gültiger HttpContext verfügbar ist.

IHttpContextAccessor kann für Komponenten verwendet werden, die auf dem Server statisch gerendert werden. Es wird jedoch empfohlen, dies nach Möglichkeit zu vermeiden.

HttpContext kann nur in statisch gerenderten Stammkomponenten für allgemeine Aufgaben als kaskadierender Parameter verwendet werden, z. B. beim Überprüfen und Ändern von Headern oder anderen Eigenschaften in der App-Komponente (Components/App.razor). Der Wert lautet immer null zum interaktiven Rendern.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Für Szenarios, in denen HttpContext in interaktiven Komponenten erforderlich ist, empfehlen wir, die Daten über den permanenten Komponentenstatus vom Server zu übertragen. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Verwenden Sie IHttpContextAccessor/HttpContext nicht direkt oder indirekt in den Razor-Komponenten serverseitiger Blazor-Apps. Blazor-Apps werden außerhalb des ASP.NET Core-Pipelinekontexts ausgeführt. Die Verfügbarkeit von HttpContext in IHttpContextAccessor kann nicht sichergestellt, und es ist auch nicht gewährleistet, dass HttpContext den Kontext zum Starten der Blazor-App enthält.

Der empfohlene Ansatz für das Übergeben des Anforderungsstatus an die Blazor-App erfolgt über Stammkomponentenparameter während des anfänglichen Renderings der App. Alternativ kann die App die Daten in einen bereichsbezogenen Dienst im Initialisierungslebenszyklusereignis der Stammkomponente kopieren, um sie in der gesamten App zu verwenden. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Ein wichtiger Aspekt der serverseitigen Blazor-Sicherheit ist, dass der Benutzer, der an eine bestimmte Verbindung angefügt ist, möglicherweise irgendwann aktualisiert wird, nachdem die Blazor-Verbindung hergestellt wurde, der IHttpContextAccessor aber nicht aktualisiert wird. Weitere Informationen zum Beheben dieses Problems mit benutzerdefinierten Diensten finden Sie unter Zusätzliche serverseitige Sicherheitsszenarios für ASP.NET Core Blazor.

HttpContext kapselt sämtliche Informationen zu einer einzelnen HTTP-Anforderung und -Antwort. Eine HttpContext-Instanz wird initialisiert, wenn eine HTTP-Anforderung empfangen wird. Auf die HttpContext-Instanz kann von Middleware und App-Frameworks wie Web-API-Controllern, Razor Pages, SignalR, gRPC und mehr zugegriffen werden.

Informationen zur Verwendung von HttpContext mit einer HTTP-Anforderung und -Antwort finden Sie unter Verwenden von HttpContext in ASP.NET Core.

Zugreifen auf HttpContext aus Razor Pages

Das PageModel von Razor Pages stellt die PageModel.HttpContext-Eigenschaft zur Verfügung:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var message = HttpContext.Request.PathBase;

        // ...
    }
}

Dieselbe Eigenschaft kann in der entsprechenden Razor-Seitenansicht verwendet werden:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Zugreifen auf HttpContext aus einer Razor-Ansicht in MVC

Razor-Ansichten im MVC-Muster machen HttpContext über die RazorPage.Context-Eigenschaft in der Ansicht verfügbar. Im folgenden Beispiel wird der aktuelle Benutzername in einer Intranet-App abgerufen, die die Windows-Authentifizierung verwendet:

@{
    var username = Context.User.Identity.Name;

    // ...
}

Zugreifen auf HttpContext aus einem Controller

Controller machen die ControllerBase.HttpContext-Eigenschaft verfügbar:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var pathBase = HttpContext.Request.PathBase;

        // ...

        return View();
    }
}

Zugreifen auf HttpContext aus Middleware

Wenn Sie mit benutzerdefinierten Middlewarekomponenten arbeiten, wird HttpContext an die Methode Invoke oder InvokeAsync übergeben:

public class MyCustomMiddleware
{
    public Task InvokeAsync(HttpContext context)
    {
        // ...
    }
}

Zugreifen auf HttpContext aus benutzerdefinierten Komponenten

Für andere Framework- und benutzerdefinierte Komponenten, die Zugriff auf HttpContext erfordern, wird empfohlen, eine Abhängigkeit mithilfe des integrierten Abhängigkeitsinjektionscontainers zu registrieren. Der Abhängigkeitsinjektionscontainer stellt IHttpContextAccessor allen Klassen zur Verfügung, die ihn in ihren Konstruktoren als Abhängigkeit deklarieren:

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllersWithViews();
     services.AddHttpContextAccessor();
     services.AddTransient<IUserRepository, UserRepository>();
}

Im folgenden Beispiel:

  • UserRepository deklariert seine Abhängigkeit von IHttpContextAccessor.
  • Die Abhängigkeit wird bereitgestellt, wenn die Abhängigkeitsinjektion die Abhängigkeitskette auflöst und eine UserRepository-Instanz erstellt.
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);
    }
}

Zugreifen auf HttpContext aus einem Hintergrundthread

HttpContext ist nicht threadsicher. Eigenschaften von HttpContext außerhalb der Verarbeitung einer Anforderung zu lesen oder zu schreiben kann zu einer NullReferenceException führen.

Hinweis

Wenn Ihre App sporadische NullReferenceException-Fehler erzeugt, überprüfen Sie die Teile des Codes, die die Hintergrundverarbeitung starten oder die Verarbeitung fortsetzen, nachdem eine Anforderung erfüllt wurde. Suchen Sie nach Fehlern, wie das Definieren einer Controllermethode als async void.

So werden Hintergrundaufgaben mit HttpContext-Daten sicher ausgeführt

  • Kopieren Sie die benötigten Daten während der Verarbeitung der Anforderung.
  • Übergeben Sie die kopierten Daten an eine Hintergrundaufgabe.
  • Verweisen Sie in parallelen Aufgaben nicht auf HttpContext-Daten. Extrahieren Sie die erforderlichen Daten aus dem Kontext, bevor Sie die parallelen Aufgaben starten.

Um unsicheren Code zu vermeiden, übergeben Sie HttpContext niemals an eine Methode, die im Hintergrund arbeitet. Übergeben Sie stattdessen die erforderlichen Daten. Im folgenden Beispiel wird SendEmailCore aufgerufen, um mit dem Senden einer E-Mail zu beginnen. correlationId wird an SendEmailCore übergeben, nicht an HttpContext. Die Codeausführung wartet nicht auf den Abschluss von SendEmailCore:

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 Komponenten (Blazor)

IHttpContextAccessor muss mit interaktivem Rendering vermieden werden, da kein gültiger HttpContext verfügbar ist.

IHttpContextAccessor kann für Komponenten verwendet werden, die auf dem Server statisch gerendert werden. Es wird jedoch empfohlen, dies nach Möglichkeit zu vermeiden.

HttpContext kann nur in statisch gerenderten Stammkomponenten für allgemeine Aufgaben als kaskadierender Parameter verwendet werden, z. B. beim Überprüfen und Ändern von Headern oder anderen Eigenschaften in der App-Komponente (Components/App.razor). Der Wert lautet immer null zum interaktiven Rendern.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Für Szenarios, in denen HttpContext in interaktiven Komponenten erforderlich ist, empfehlen wir, die Daten über den permanenten Komponentenstatus vom Server zu übertragen. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Verwenden Sie IHttpContextAccessor/HttpContext nicht direkt oder indirekt in den Razor-Komponenten serverseitiger Blazor-Apps. Blazor-Apps werden außerhalb des ASP.NET Core-Pipelinekontexts ausgeführt. Die Verfügbarkeit von HttpContext in IHttpContextAccessor kann nicht sichergestellt, und es ist auch nicht gewährleistet, dass HttpContext den Kontext zum Starten der Blazor-App enthält.

Der empfohlene Ansatz für das Übergeben des Anforderungsstatus an die Blazor-App erfolgt über Stammkomponentenparameter während des anfänglichen Renderings der App. Alternativ kann die App die Daten in einen bereichsbezogenen Dienst im Initialisierungslebenszyklusereignis der Stammkomponente kopieren, um sie in der gesamten App zu verwenden. Weitere Informationen finden Sie unter Zusätzliche serverseitige Sicherheitsszenarien für Blazor in ASP.NET Core.

Ein wichtiger Aspekt der serverseitigen Blazor-Sicherheit ist, dass der Benutzer, der an eine bestimmte Verbindung angefügt ist, möglicherweise irgendwann aktualisiert wird, nachdem die Blazor-Verbindung hergestellt wurde, der IHttpContextAccessor aber nicht aktualisiert wird. Weitere Informationen zum Beheben dieses Problems mit benutzerdefinierten Diensten finden Sie unter Zusätzliche serverseitige Sicherheitsszenarios für ASP.NET Core Blazor.