Sdílet prostřednictvím


Přístup HttpContext v ASP.NET Core

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

HttpContext Zapouzdřuje všechny informace o jednotlivých požadavcích a odpovědích HTTP. Instance HttpContext se inicializuje při přijetí požadavku HTTP. Instance HttpContext je přístupná prostřednictvím middlewaru a aplikačních architektur, jako jsou kontrolery webového rozhraní API, Razor Stránky, SignalR, gRPC a další.

Informace o použití HttpContext s požadavkem a odpovědí HTTP naleznete v tématu Použití HttpContext v ASP.NET Core.

Přístup HttpContext ze Razor stránek

PageModel Stránky Razor zpřístupňuje PageModel.HttpContext vlastnost:

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

        // ...
    }
}

Stejnou vlastnost lze použít v odpovídajícím Razor zobrazení stránky:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Přístup HttpContext ze Razor zobrazení v MVC

Razor zobrazení v vzoru MVC zpřístupňují HttpContext prostřednictvím RazorPage.Context vlastnosti v zobrazení. Následující příklad načte aktuální uživatelské jméno v intranetové aplikaci pomocí ověřování systému Windows:

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

    // ...
}

Přístup HttpContext z kontroleru

Kontrolery zpřístupňují ControllerBase.HttpContext vlastnost:

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

        // ...

        return View();
    }
}

Přístup HttpContext z minimálních rozhraní API

Pokud chcete použít HttpContext z minimálních rozhraní API, přidejte HttpContext parametr:

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

Přístup HttpContext z middlewaru

Pokud chcete použít HttpContext z vlastních komponent middlewaru HttpContext Invoke , použijte parametr předaný do metody nebo InvokeAsync metody:

public class MyCustomMiddleware
{
    // ...

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

Přístup HttpContext z SignalR

Chcete-li použít HttpContext z SignalR, zavolejte metodu GetHttpContext :Hub.Context

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

        // ...
    }
}

Přístup HttpContext z metod gRPC

Pokud chcete použít HttpContext metody gRPC, přečtěte si téma Řešení HttpContext v metodách gRPC.

Přístup HttpContext z vlastních komponent

U jiných architektur a vlastních komponent, které vyžadují přístupHttpContext, se doporučuje registrovat závislost pomocí integrovaného kontejneru injektáže závislostí (DI). Kontejner DI dodává IHttpContextAccessor všechny třídy, které ho deklarují jako závislost v jejich konstruktorech:

var builder = WebApplication.CreateBuilder(args);

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

V následujícím příkladu:

  • UserRepository deklaruje jeho závislost na IHttpContextAccessor.
  • Závislost se zadává, když DI vyřeší řetěz závislostí a vytvoří instanci 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 přístup z vlákna na pozadí

HttpContext není bezpečný pro přístup z více vláken. Čtení nebo zápis vlastností HttpContext mimo zpracování požadavku může mít za následek .NullReferenceException

Poznámka:

Pokud vaše aplikace generuje občasné NullReferenceException chyby, zkontrolujte části kódu, které spouští zpracování na pozadí nebo které po dokončení požadavku pokračují ve zpracování. Hledejte chyby, například definování metody kontroleru jako async void.

Bezpečné práce na pozadí s daty HttpContext :

  • Během zpracování požadavku zkopírujte požadovaná data.
  • Předejte zkopírovaná data do úlohy na pozadí.
  • Neodkazujte na HttpContext data v paralelních úlohách. Před spuštěním paralelních úloh extrahujte data potřebná z kontextu.

Abyste se vyhnuli nebezpečnému kódu, nikdy nepředávejte HttpContext metodu, která funguje na pozadí. Místo toho předejte požadovaná data. V následujícím příkladu SendEmail volání SendEmailCoreAsync , která začnou posílat e-maily. Hodnota hlavičky X-Correlation-Id se předá SendEmailCoreAsync místo HttpContext. Provádění kódu nečeká na SendEmailCoreAsync dokončení:

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 v Razor součástech (Blazor)

IHttpContextAccessor musí se vyhnout interaktivnímu vykreslování, protože není k dispozici platný HttpContext .

IHttpContextAccessor lze použít pro součásti, které jsou staticky vykresleny na serveru. Pokud je to ale možné, doporučujeme ho vyhnout.

HttpContext lze použít jako kaskádový parametr pouze v staticky vykreslovaných kořenových komponentách pro obecné úlohy, jako je kontrola a úprava hlaviček nebo jiných vlastností v komponentě App (Components/App.razor). Hodnota je vždy null určená pro interaktivní vykreslování.

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

Pro scénáře, ve HttpContext kterých se vyžaduje v interaktivních komponentách, doporučujeme tok dat přes trvalý stav komponenty ze serveru. Další informace najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.

Nepoužívejte IHttpContextAccessor/HttpContext přímo ani nepřímo v Razor komponentách serverových Blazor aplikací. Blazor aplikace běží mimo kontext kanálu ASP.NET Core. Není HttpContext zaručeno, že bude k dispozici v rámci aplikace IHttpContextAccessora HttpContext není zaručeno, že bude obsahovat kontext, který aplikaci spustil Blazor .

Doporučený postup pro předávání stavu požadavku do Blazor aplikace je prostřednictvím parametrů kořenové komponenty během počátečního vykreslování aplikace. Případně může aplikace zkopírovat data do vymezené služby v události životního cyklu inicializace kořenové komponenty pro použití v celé aplikaci. Další informace najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.

Důležitým aspektem zabezpečení na straně Blazor serveru je, že se uživatel připojený k danému okruhu může v určitém okamžiku Blazor po navázání okruhu aktualizovat, ale IHttpContextAccessor neaktualizuje se. Další informace o řešení této situace s vlastními službami najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.

HttpContext Zapouzdřuje všechny informace o jednotlivých požadavcích a odpovědích HTTP. Instance HttpContext se inicializuje při přijetí požadavku HTTP. Instance HttpContext je přístupná prostřednictvím middlewaru a aplikačních architektur, jako jsou kontrolery webového rozhraní API, Razor Stránky, SignalR, gRPC a další.

Informace o použití HttpContext s požadavkem a odpovědí HTTP naleznete v tématu Použití HttpContext v ASP.NET Core.

Přístup HttpContext ze Razor stránek

PageModel Stránky Razor zpřístupňuje PageModel.HttpContext vlastnost:

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

        // ...
    }
}

Stejnou vlastnost lze použít v odpovídajícím Razor zobrazení stránky:

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Přístup HttpContext ze Razor zobrazení v MVC

Razor zobrazení v vzoru MVC zpřístupňují HttpContext prostřednictvím RazorPage.Context vlastnosti v zobrazení. Následující příklad načte aktuální uživatelské jméno v intranetové aplikaci pomocí ověřování systému Windows:

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

    // ...
}

Přístup HttpContext z kontroleru

Kontrolery zpřístupňují ControllerBase.HttpContext vlastnost:

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

        // ...

        return View();
    }
}

Přístup HttpContext z middlewaru

Při práci s vlastními komponentami HttpContext middlewaru se předá do Invoke metody nebo InvokeAsync metody:

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

Přístup HttpContext z vlastních komponent

U jiných architektur a vlastních komponent, které vyžadují přístupHttpContext, se doporučuje registrovat závislost pomocí integrovaného kontejneru injektáže závislostí (DI). Kontejner DI dodává IHttpContextAccessor všechny třídy, které ho deklarují jako závislost v jejich konstruktorech:

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

V následujícím příkladu:

  • UserRepository deklaruje jeho závislost na IHttpContextAccessor.
  • Závislost se zadává, když DI vyřeší řetěz závislostí a vytvoří instanci 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 přístup z vlákna na pozadí

HttpContext není bezpečný pro přístup z více vláken. Čtení nebo zápis vlastností HttpContext mimo zpracování požadavku může mít za následek .NullReferenceException

Poznámka:

Pokud vaše aplikace generuje občasné NullReferenceException chyby, zkontrolujte části kódu, které spouští zpracování na pozadí nebo které po dokončení požadavku pokračují ve zpracování. Hledejte chyby, například definování metody kontroleru jako async void.

Bezpečné práce na pozadí s daty HttpContext :

  • Během zpracování požadavku zkopírujte požadovaná data.
  • Předejte zkopírovaná data do úlohy na pozadí.
  • Neodkazujte na HttpContext data v paralelních úlohách. Před spuštěním paralelních úloh extrahujte data potřebná z kontextu.

Abyste se vyhnuli nebezpečnému kódu, nikdy nepředávejte HttpContext metodu, která funguje na pozadí. Místo toho předejte požadovaná data. V následujícím příkladu je volána k SendEmailCore zahájení odesílání e-mailu. Je correlationId předán SendEmailCore, ne HttpContext. Provádění kódu nečeká na SendEmailCore dokončení:

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 v Razor součástech (Blazor)

IHttpContextAccessor musí se vyhnout interaktivnímu vykreslování, protože není k dispozici platný HttpContext .

IHttpContextAccessor lze použít pro součásti, které jsou staticky vykresleny na serveru. Pokud je to ale možné, doporučujeme ho vyhnout.

HttpContext lze použít jako kaskádový parametr pouze v staticky vykreslovaných kořenových komponentách pro obecné úlohy, jako je kontrola a úprava hlaviček nebo jiných vlastností v komponentě App (Components/App.razor). Hodnota je vždy null určená pro interaktivní vykreslování.

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

Pro scénáře, ve HttpContext kterých se vyžaduje v interaktivních komponentách, doporučujeme tok dat přes trvalý stav komponenty ze serveru. Další informace najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.

Nepoužívejte IHttpContextAccessor/HttpContext přímo ani nepřímo v Razor komponentách serverových Blazor aplikací. Blazor aplikace běží mimo kontext kanálu ASP.NET Core. Není HttpContext zaručeno, že bude k dispozici v rámci aplikace IHttpContextAccessora HttpContext není zaručeno, že bude obsahovat kontext, který aplikaci spustil Blazor .

Doporučený postup pro předávání stavu požadavku do Blazor aplikace je prostřednictvím parametrů kořenové komponenty během počátečního vykreslování aplikace. Případně může aplikace zkopírovat data do vymezené služby v události životního cyklu inicializace kořenové komponenty pro použití v celé aplikaci. Další informace najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.

Důležitým aspektem zabezpečení na straně Blazor serveru je, že se uživatel připojený k danému okruhu může v určitém okamžiku Blazor po navázání okruhu aktualizovat, ale IHttpContextAccessor neaktualizuje se. Další informace o řešení této situace s vlastními službami najdete v tématu Další scénáře zabezpečení na straně serveru ASP.NET CoreBlazor.