Доступ HttpContext
в ASP.NET Core
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 8 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 8 этой статьи.
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
возможности.
IHttpContextAccessor можно использовать для компонентов, которые статически отрисовываются на сервере. Тем не менее, мы рекомендуем избегать его, если это возможно.
HttpContext можно использовать в качестве каскадного параметра только в статически отрисованных корневых компонентах для общих задач, таких как проверка и изменение заголовков или других свойств компонента App
(Components/App.razor
). Значение всегда null
предназначено для интерактивной отрисовки.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
В сценариях, где HttpContext требуется в интерактивных компонентах, рекомендуется передавать данные через постоянное состояние компонента с сервера. Дополнительные сведения см . на стороне сервера ASP.NET Основных Blazor дополнительных сценариев безопасности.
Не используйте IHttpContextAccessor/HttpContext непосредственно или косвенно в Razor компонентах серверных Blazor приложений. Blazor приложения выполняются вне контекста конвейера ASP.NET Core. Он HttpContext не гарантируется, что он доступен в пределах приложения IHttpContextAccessorи HttpContext не гарантируется, что он будет содержать контекст, который запустил Blazor приложение.
Рекомендуемый подход для передачи состояния Blazor запроса приложению осуществляется через параметры корневого компонента во время первоначальной отрисовки приложения. Кроме того, приложение может скопировать данные в службу с областью действия в событии жизненного цикла инициализации корневого компонента для использования в приложении. Дополнительные сведения см . на стороне сервера ASP.NET Основных Blazor дополнительных сценариев безопасности.
Критически важный аспект безопасности на стороне Blazor сервера заключается в том, что пользователь, подключенный к заданному каналу, может быть обновлен в какой-то момент после Blazor установки канала, но IHttpContextAccessorне обновляется. Дополнительные сведения об устранении этой ситуации с пользовательскими службами см. в дополнительных сценариях безопасности на стороне сервера ASP.NET CoreBlazor.
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
возможности.
IHttpContextAccessor можно использовать для компонентов, которые статически отрисовываются на сервере. Тем не менее, мы рекомендуем избегать его, если это возможно.
HttpContext можно использовать в качестве каскадного параметра только в статически отрисованных корневых компонентах для общих задач, таких как проверка и изменение заголовков или других свойств компонента App
(Components/App.razor
). Значение всегда null
предназначено для интерактивной отрисовки.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
В сценариях, где HttpContext требуется в интерактивных компонентах, рекомендуется передавать данные через постоянное состояние компонента с сервера. Дополнительные сведения см . на стороне сервера ASP.NET Основных Blazor дополнительных сценариев безопасности.
Не используйте IHttpContextAccessor/HttpContext непосредственно или косвенно в Razor компонентах серверных Blazor приложений. Blazor приложения выполняются вне контекста конвейера ASP.NET Core. Он HttpContext не гарантируется, что он доступен в пределах приложения IHttpContextAccessorи HttpContext не гарантируется, что он будет содержать контекст, который запустил Blazor приложение.
Рекомендуемый подход для передачи состояния Blazor запроса приложению осуществляется через параметры корневого компонента во время первоначальной отрисовки приложения. Кроме того, приложение может скопировать данные в службу с областью действия в событии жизненного цикла инициализации корневого компонента для использования в приложении. Дополнительные сведения см . на стороне сервера ASP.NET Основных Blazor дополнительных сценариев безопасности.
Критически важный аспект безопасности на стороне Blazor сервера заключается в том, что пользователь, подключенный к заданному каналу, может быть обновлен в какой-то момент после Blazor установки канала, но IHttpContextAccessorне обновляется. Дополнительные сведения об устранении этой ситуации с пользовательскими службами см. в дополнительных сценариях безопасности на стороне сервера ASP.NET CoreBlazor.
ASP.NET Core