Поделиться через


Доступ HttpContext в ASP.NET Core

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 9 этой статьи.

HttpContext инкапсулирует все сведения о отдельном HTTP-запросе и ответе. Экземпляр HttpContext инициализируется при получении HTTP-запроса. Экземпляр HttpContext доступен по промежуточному слоям и платформам приложений, таким как контроллеры веб-API, Razor Pages, SignalRgRPC и многое другое.

Сведения об использовании HttpContext с HTTP-запросом и ответом см. в разделе "Использование HttpContext" в ASP.NET Core.

Доступ HttpContext из Razor страниц

Класс Razor Pages PageModel предоставляет свойство PageModel.HttpContext.

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

        // ...
    }
}

То же свойство можно использовать в соответствующем представлении страницы Razor.

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Доступ HttpContext из Razor представления в MVC

Представления Razor в шаблоне MVC предоставляют HttpContext через свойство RazorPage.Context в представлении. В следующем примере имя текущего пользователя в приложении интрасети извлекается с использованием проверки подлинности Windows:

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

    // ...
}

Доступ HttpContext с контроллера

Контроллеры предоставляют свойство ControllerBase.HttpContext.

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

        // ...

        return View();
    }
}

Доступ HttpContext из минимальных API

Для использования HttpContext через минимальные API, добавьте параметр HttpContext:

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

Доступ HttpContext из ПО промежуточного слоя

Для использования HttpContext из пользовательского ПО промежуточного слоя используйте параметр HttpContext, передаваемый в метод Invoke или InvokeAsync:

public class MyCustomMiddleware
{
    // ...

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

Доступ HttpContext из SignalR

Чтобы использовать HttpContext из SignalR, вызовите метод GetHttpContext для Hub.Context:

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

        // ...
    }
}

Доступ HttpContext из методов gRPC

Сведения об использовании HttpContext из методов gRPC см. в разделе "Разрешение HttpContext " в методах gRPC.

Доступ HttpContext из пользовательских компонентов

Для других компонентов платформы и пользовательских компонентов, которым требуется доступ к HttpContext, рекомендуется зарегистрировать зависимость с помощью встроенного контейнера внедрения зависимостей (DI). Контейнер DI предоставляет IHttpContextAccessor для всех классов для объявления в качестве зависимости в своих конструкторах.

var builder = WebApplication.CreateBuilder(args);

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

В следующем примере :

  • UserRepository объявляет зависимость от IHttpContextAccessor.
  • Зависимость предоставляется, если DI разрешает цепочку зависимостей и создает экземпляр 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 доступ из фонового потока

HttpContext не является потокобезопасным. Чтение или запись свойств HttpContext за пределами обработки запроса может привести к NullReferenceException.

Примечание.

Если приложение генерирует случайные ошибки NullReferenceException, просмотрите части кода, которые запускают фоновую обработку или продолжают обработку после выполнения запроса. Ищите ошибки, например, как определение метода контроллера в качестве async void.

Для безопасного выполнения фоновой работы с данными HttpContext:

  • Скопируйте необходимые данные во время обработки запроса.
  • Передайте скопированные данные в фоновую задачу.
  • Не ссылайтесь на данные HttpContext в параллельных задачах. Перед запуском параллельных задач извлеките необходимые данные из контекста.

Чтобы избежать небезопасного кода, никогда не передавайте HttpContext в метод, который выполняет фоновую работу. Вместо этого передайте нужные данные. В приведенном ниже примере SendEmail вызывает SendEmailCoreAsync для запуска отправки сообщения электронной почты. Значение заголовка X-Correlation-Id передается в SendEmailCoreAsync, а не в HttpContext. Код не ждет завершения выполнения метода 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 в Razor компонентах (Blazor)

Дополнительные сведения см. в разделе IHttpContextAccessor/HttpContext в приложениях ASP.NET Core Blazor.

HttpContext инкапсулирует все сведения о отдельном HTTP-запросе и ответе. Экземпляр HttpContext инициализируется при получении HTTP-запроса. Экземпляр HttpContext доступен по промежуточному слоям и платформам приложений, таким как контроллеры веб-API, Razor Pages, SignalRgRPC и многое другое.

Сведения об использовании HttpContext с HTTP-запросом и ответом см. в разделе "Использование HttpContext" в ASP.NET Core.

Доступ HttpContext из Razor страниц

Класс Razor Pages PageModel предоставляет свойство PageModel.HttpContext.

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

        // ...
    }
}

То же свойство можно использовать в соответствующем представлении страницы Razor.

@page
@model IndexModel

@{
    var message = HttpContext.Request.PathBase;

    // ...
}

Доступ HttpContext из Razor представления в MVC

Представления Razor в шаблоне MVC предоставляют HttpContext через свойство RazorPage.Context в представлении. В следующем примере имя текущего пользователя в приложении интрасети извлекается с использованием проверки подлинности Windows:

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

    // ...
}

Доступ HttpContext с контроллера

Контроллеры предоставляют свойство ControllerBase.HttpContext.

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

        // ...

        return View();
    }
}

Доступ HttpContext из ПО промежуточного слоя

При работе с компонентами пользовательского ПО промежуточного слоя HttpContext передается в метод Invoke или InvokeAsync.

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

Доступ HttpContext из пользовательских компонентов

Для других компонентов платформы и пользовательских компонентов, которым требуется доступ к HttpContext, рекомендуется зарегистрировать зависимость с помощью встроенного контейнера внедрения зависимостей (DI). Контейнер DI предоставляет IHttpContextAccessor для всех классов для объявления в качестве зависимости в своих конструкторах.

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

В следующем примере :

  • UserRepository объявляет зависимость от IHttpContextAccessor.
  • Зависимость предоставляется, если DI разрешает цепочку зависимостей и создает экземпляр 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 доступ из фонового потока

HttpContext не является потокобезопасным. Чтение или запись свойств HttpContext за пределами обработки запроса может привести к NullReferenceException.

Примечание.

Если приложение генерирует случайные ошибки NullReferenceException, просмотрите части кода, которые запускают фоновую обработку или продолжают обработку после выполнения запроса. Ищите ошибки, например, как определение метода контроллера в качестве async void.

Для безопасного выполнения фоновой работы с данными HttpContext:

  • Скопируйте необходимые данные во время обработки запроса.
  • Передайте скопированные данные в фоновую задачу.
  • Не ссылайтесь на данные HttpContext в параллельных задачах. Перед запуском параллельных задач извлеките необходимые данные из контекста.

Чтобы избежать небезопасного кода, никогда не передавайте HttpContext в метод, который выполняет фоновую работу. Вместо этого передайте нужные данные. В приведенном ниже примере метод SendEmailCore вызывается для запуска отправки сообщения электронной почты. correlationId передается в SendEmailCore, а не в HttpContext. Код не ждет завершения выполнения метода 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 в Razor компонентах (Blazor)

Дополнительные сведения см. в разделе IHttpContextAccessor/HttpContext в приложениях ASP.NET Core Blazor.