Dostęp HttpContext w ASP.NET Core

HttpContext Hermetyzuje wszystkie informacje dotyczące pojedynczego żądania HTTP i odpowiedzi. Wystąpienie HttpContext jest inicjowane po odebraniu żądania HTTP. Wystąpienie HttpContext jest dostępne przez oprogramowanie pośredniczące i struktury aplikacji, takie jak kontrolery interfejsu API sieci Web, Razor strony, SignalR, gRPC i inne.

Aby uzyskać informacje na temat używania z HttpContext żądaniem HTTP i odpowiedzią, zobacz Use HttpContext in ASP.NET Core (Używanie obiektu HttpContext w programie ASP.NET Core).

Dostęp HttpContext ze Razor stron

Właściwość Razor Pages PageModel uwidacznia PageModel.HttpContext :

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

        // ...
    }
}

Tej samej właściwości można używać w odpowiednim Razor widoku strony:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Dostęp HttpContext z Razor widoku w mvc

Razor widoki we wzorcu MVC uwidaczniają HttpContext właściwość za pośrednictwem RazorPage.Context właściwości w widoku. Poniższy przykład pobiera bieżącą nazwę użytkownika w aplikacji intranetowej przy użyciu uwierzytelniania systemu Windows:

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

    // ...
}

Dostęp HttpContext z kontrolera

Kontrolery uwidaczniają ControllerBase.HttpContext właściwość:

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

        // ...

        return View();
    }
}

Dostęp HttpContext z minimalnych interfejsów API

Aby użyć z HttpContext minimalnych interfejsów API, dodaj HttpContext parametr:

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

Dostęp HttpContext z oprogramowania pośredniczącego

Aby użyć z HttpContext niestandardowych składników oprogramowania pośredniczącego, użyj parametru przekazanego HttpContextInvoke do metody or InvokeAsync :

public class MyCustomMiddleware
{
    // ...

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

Dostęp HttpContext z SignalR

Aby użyć metody HttpContext z SignalRklasy , wywołaj metodę GetHttpContext w metodzie w metodzie :Hub.Context

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

        // ...
    }
}

Dostęp HttpContext z metod gRPC

Aby użyć z HttpContext metod gRPC, zobacz Rozwiązywanie HttpContext w metodach gRPC.

Dostęp HttpContext ze składników niestandardowych

W przypadku innych struktur i składników niestandardowych, które wymagają dostępu do HttpContextprogramu , zalecane jest zarejestrowanie zależności przy użyciu wbudowanego kontenera wstrzykiwania zależności (DI). Kontener DI dostarcza IHttpContextAccessor element do wszystkich klas, które deklarują ją jako zależność w swoich konstruktorach:

var builder = WebApplication.CreateBuilder(args);

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

W poniższym przykładzie:

  • UserRepository deklaruje zależność od IHttpContextAccessorelementu .
  • Zależność jest dostarczana, gdy di rozwiązuje łańcuch zależności i tworzy wystąpienie klasy 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;

        // ...
    }
}

HttpContext dostęp z wątku w tle

HttpContext nie jest bezpieczny wątkowo. Odczytywanie lub zapisywanie właściwości HttpContext poza przetwarzaniem żądania może spowodować, że NullReferenceExceptionelement .

Uwaga

Jeśli aplikacja generuje sporadyczne NullReferenceException błędy, przejrzyj części kodu, które rozpoczynają przetwarzanie w tle lub które kontynuują przetwarzanie po zakończeniu żądania. Poszukaj błędów, takich jak zdefiniowanie metody kontrolera jako async void.

Aby bezpiecznie wykonywać pracę w tle z HttpContext danymi:

  • Skopiuj wymagane dane podczas przetwarzania żądań.
  • Przekaż skopiowane dane do zadania w tle.
  • Nie odwołuj się do HttpContext danych równoległych. Wyodrębnij dane potrzebne z kontekstu przed rozpoczęciem zadań równoległych.

Aby uniknąć niebezpiecznego kodu, nigdy nie należy przekazywać HttpContext do metody, która działa w tle. Przekaż wymagane dane. W poniższym przykładzie SendEmail wywołania SendEmailCoreAsync w celu rozpoczęcia wysyłania wiadomości e-mail. Wartość nagłówka X-Correlation-Id jest przekazywana SendEmailCoreAsync zamiast .HttpContext Wykonanie kodu nie czeka na SendEmailCoreAsync ukończenie:

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 w Razor składnikach (Blazor)

IHttpContextAccessor należy unikać renderowania interakcyjnego, ponieważ nie ma prawidłowej HttpContext dostępności.

IHttpContextAccessor Może służyć do składników, które są statycznie renderowane na serwerze. Zalecamy jednak unikanie go, jeśli to możliwe.

HttpContextMoże być używany jako parametr kaskadowy tylko w statycznie renderowanych składnikach głównych dla zadań ogólnych, takich jak inspekcja i modyfikowanie nagłówków lub innych właściwości w składniku App (Components/App.razor). Wartość jest zawsze null dla renderowania interakcyjnego.

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

W przypadku scenariuszy, w których HttpContext element jest wymagany w składnikach interaktywnych, zalecamy przepływ danych za pośrednictwem stanu trwałego składnika z serwera. Aby uzyskać więcej informacji, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.

Nie używaj IHttpContextAccessor/HttpContext bezpośrednio ani pośrednio składników Razor aplikacji po stronie Blazor serwera. Blazor aplikacje działają poza kontekstem potoku ASP.NET Core. Nie HttpContext ma gwarancji, że element jest dostępny w programie IHttpContextAccessori HttpContext nie ma gwarancji, że przechowuje kontekst, w ramach którego uruchomiono aplikację Blazor .

Zalecaną metodą przekazywania stanu żądania do Blazor aplikacji są parametry składnika głównego podczas początkowego renderowania aplikacji. Alternatywnie aplikacja może skopiować dane do usługi o określonym zakresie w zdarzeniu cyklu życia inicjowania składnika głównego do użycia w całej aplikacji. Aby uzyskać więcej informacji, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.

Krytycznym aspektem zabezpieczeń po stronie Blazor serwera jest to, że użytkownik dołączony do danego obwodu może zostać zaktualizowany w pewnym momencie po ustanowieniu obwoduBlazor, ale IHttpContextAccessornie został zaktualizowany. Aby uzyskać więcej informacji na temat rozwiązywania tej sytuacji z usługami niestandardowymi, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.

HttpContext Hermetyzuje wszystkie informacje dotyczące pojedynczego żądania HTTP i odpowiedzi. Wystąpienie HttpContext jest inicjowane po odebraniu żądania HTTP. Wystąpienie HttpContext jest dostępne przez oprogramowanie pośredniczące i struktury aplikacji, takie jak kontrolery interfejsu API sieci Web, Razor strony, SignalR, gRPC i inne.

Aby uzyskać informacje na temat używania z HttpContext żądaniem HTTP i odpowiedzią, zobacz Use HttpContext in ASP.NET Core (Używanie obiektu HttpContext w programie ASP.NET Core).

Dostęp HttpContext ze Razor stron

Właściwość Razor Pages PageModel uwidacznia PageModel.HttpContext :

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

        // ...
    }
}

Tej samej właściwości można używać w odpowiednim Razor widoku strony:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Dostęp HttpContext z Razor widoku w mvc

Razor widoki we wzorcu MVC uwidaczniają HttpContext właściwość za pośrednictwem RazorPage.Context właściwości w widoku. Poniższy przykład pobiera bieżącą nazwę użytkownika w aplikacji intranetowej przy użyciu uwierzytelniania systemu Windows:

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

    // ...
}

Dostęp HttpContext z kontrolera

Kontrolery uwidaczniają ControllerBase.HttpContext właściwość:

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

        // ...

        return View();
    }
}

Dostęp HttpContext z oprogramowania pośredniczącego

Podczas pracy z niestandardowymi składnikami HttpContext oprogramowania pośredniczącego jest przekazywany do Invoke metody lub InvokeAsync :

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

Dostęp HttpContext ze składników niestandardowych

W przypadku innych struktur i składników niestandardowych, które wymagają dostępu do HttpContextprogramu , zalecane jest zarejestrowanie zależności przy użyciu wbudowanego kontenera wstrzykiwania zależności (DI). Kontener DI dostarcza IHttpContextAccessor element do wszystkich klas, które deklarują ją jako zależność w swoich konstruktorach:

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

W poniższym przykładzie:

  • UserRepository deklaruje zależność od IHttpContextAccessorelementu .
  • Zależność jest dostarczana, gdy di rozwiązuje łańcuch zależności i tworzy wystąpienie klasy 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 dostęp z wątku w tle

HttpContext nie jest bezpieczny wątkowo. Odczytywanie lub zapisywanie właściwości HttpContext poza przetwarzaniem żądania może spowodować, że NullReferenceExceptionelement .

Uwaga

Jeśli aplikacja generuje sporadyczne NullReferenceException błędy, przejrzyj części kodu, które rozpoczynają przetwarzanie w tle lub które kontynuują przetwarzanie po zakończeniu żądania. Poszukaj błędów, takich jak zdefiniowanie metody kontrolera jako async void.

Aby bezpiecznie wykonywać pracę w tle z HttpContext danymi:

  • Skopiuj wymagane dane podczas przetwarzania żądań.
  • Przekaż skopiowane dane do zadania w tle.
  • Nie odwołuj się do HttpContext danych równoległych. Wyodrębnij dane potrzebne z kontekstu przed rozpoczęciem zadań równoległych.

Aby uniknąć niebezpiecznego kodu, nigdy nie należy przekazywać elementu HttpContext do metody, która działa w tle. Przekaż wymagane dane. W poniższym przykładzie wywołana jest nazwana w SendEmailCore celu rozpoczęcia wysyłania wiadomości e-mail. Element correlationId jest przekazywany do SendEmailCoreelementu , a nie .HttpContext Wykonanie kodu nie czeka na SendEmailCore ukończenie:

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 w Razor składnikach (Blazor)

IHttpContextAccessor należy unikać renderowania interakcyjnego, ponieważ nie ma prawidłowej HttpContext dostępności.

IHttpContextAccessor Może służyć do składników, które są statycznie renderowane na serwerze. Zalecamy jednak unikanie go, jeśli to możliwe.

HttpContextMoże być używany jako parametr kaskadowy tylko w statycznie renderowanych składnikach głównych dla zadań ogólnych, takich jak inspekcja i modyfikowanie nagłówków lub innych właściwości w składniku App (Components/App.razor). Wartość jest zawsze null dla renderowania interakcyjnego.

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

W przypadku scenariuszy, w których HttpContext element jest wymagany w składnikach interaktywnych, zalecamy przepływ danych za pośrednictwem stanu trwałego składnika z serwera. Aby uzyskać więcej informacji, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.

Nie używaj IHttpContextAccessor/HttpContext bezpośrednio ani pośrednio składników Razor aplikacji po stronie Blazor serwera. Blazor aplikacje działają poza kontekstem potoku ASP.NET Core. Nie HttpContext ma gwarancji, że element jest dostępny w programie IHttpContextAccessori HttpContext nie ma gwarancji, że przechowuje kontekst, w ramach którego uruchomiono aplikację Blazor .

Zalecaną metodą przekazywania stanu żądania do Blazor aplikacji są parametry składnika głównego podczas początkowego renderowania aplikacji. Alternatywnie aplikacja może skopiować dane do usługi o określonym zakresie w zdarzeniu cyklu życia inicjowania składnika głównego do użycia w całej aplikacji. Aby uzyskać więcej informacji, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.

Krytycznym aspektem zabezpieczeń po stronie Blazor serwera jest to, że użytkownik dołączony do danego obwodu może zostać zaktualizowany w pewnym momencie po ustanowieniu obwoduBlazor, ale IHttpContextAccessornie został zaktualizowany. Aby uzyskać więcej informacji na temat rozwiązywania tej sytuacji z usługami niestandardowymi, zobacz Scenariusze zabezpieczeń po stronie serwera ASP.NET CoreBlazor.