在 ASP.NET Core 5.0 中访问 HttpContext

  • A+
所属分类:.NET技术
摘要

ASP.NET Core 应用通过 IHttpContextAccessor 接口及其默认实现 HttpContextAccessor 访问 HttpContext。 只有在需要访问服务内的 HttpContext 时,才有必要使用 IHttpContextAccessor。

ASP.NET Core 应用通过 IHttpContextAccessor 接口及其默认实现 HttpContextAccessor 访问 HttpContext。 只有在需要访问服务内的 HttpContext 时,才有必要使用 IHttpContextAccessor。

通过 Razor Pages 使用 HttpContext

Razor Pages PageModel 公开 HttpContext 属性:

 

public class AboutModel : PageModel{    public string Message { get; set; }     public void OnGet()    {        Message = HttpContext.Request.PathBase;    }}

通过 Razor 视图使用 HttpContext

Razor 视图通过视图上的 RazorPage.Context 属性直接公开 HttpContext。 下面的示例使用 Windows 身份验证检索 Intranet 应用中的当前用户名:

​​​​​​​

@{    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 的其他框架和自定义组件,建议使用内置的依赖项注入容器来注册依赖项。 依赖项注入容器向任意类提供 IHttpContextAccessor,以供类在自己的构造函数中将它声明为依赖项:

​​​​​​​

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

如下示例中:

  • UserRepository 声明自己对 IHttpContextAccessor 的依赖。

  • 当依赖项注入容器解析依赖链并创建 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。

要使用 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)    {        ...    }}