访问 HTTPContext

Posted

技术标签:

【中文标题】访问 HTTPContext【英文标题】:Access to HTTPContext 【发布时间】:2019-11-17 22:45:56 【问题描述】:

我已经在 Net Core 2.1 中构建了 REST API

项目分为Assemblies:

APIREST(包括控制器) MODULES(包含逻辑和存储库的模块)

我可以在模块中正确使用HTTPContext来下载JWT中保存的UserId吗?

对数据库的查询需要查询上的令牌中有关 UserId 的信息

我知道当我在控制器代码的范围内调用时,我会得到正确的值,但我也会在不同类的另一个程序集中得到它吗?

当查询范围结束时,HTTPContext内容是否被移除?

【问题讨论】:

为什么业务逻辑模块需要知道它是在 HTTP 上下文中运行的?为什么要将 HttpContext 注入业务逻辑类,只是为了让该类提取 JWT 并将其解析为 UserId?为什么不将 UserId 从控制器传递到业务逻辑?另外,请阅读How to Ask 并分享您的研究。 参见例如How do I get current user in .NET Core Web API (from JWT Token)、Access the current HttpContext in ASP.NET Core 和许多其他人。 @CodeCaster 目前,我通过直接从控制器为其准备的函数将 UserId 发送到存储库。我想知道我是否可以跳过这个并直接在模块中从 HTTPContext 下载 UserId 在业务逻辑类中注入userid参数不是更简单吗? 【参考方案1】:

HttpContext 有一个作用域生命周期,现在是依赖注入。在您无法直接访问它的地方(控制器/页面/视图),您可以注入IHttpContextAccessor,这是一个知道如何在范围内检索HttpContext 实例的单例。

public class MyClass

    private readonly IHttpContextAccessor _httpContextAccessor;

    public MyClass(IHttpContextAccessor httpContextAccessor)
    
        _httpContextAccessor = httpContextAccessor;
    

    public void MyMethod()
    
        var userId = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (userId != null)
        
            // do something
        
    

HttpContext 可能为 null,因此您需要使用 null 检查来处理它。

您当然需要在服务集合中注册MyClass,并且您还需要在需要时注入它,否则这些都不起作用。此外,默认情况下不包括IHttpContextAccessor,因为它会对性能产生不可忽视的影响。如果您想使用它,您需要将以下行添加到您的应用程序的ConfigureServices

services.AddHttpContextAccessor();

现在,说了这么多,几乎忘记了我刚刚告诉你的一切。实际上不要这样做。一个设计良好的类应该遵循 SOLID 的原则,其中之一就是它应该只做一件事,并且把它做好。在大多数情况下,某些库中的类完全不适合了解 HttpContext 之类的知识。

相反,如果您在某些方法中需要用户 ID,只需 将其传递给该方法

public void DoSomethingWithUserId(string userId)

然后,例如,在您的控制器中,您已经可以访问HttpContext

myClass.DoSomethingWithUserId(User.FindFirstValue(ClaimTypes.NameIdenfiier));

【讨论】:

以上是关于访问 HTTPContext的主要内容,如果未能解决你的问题,请参考以下文章

Sharepoint 根据文件相对路径获取操作SPFolder

ASP.NET Core 5 - 如何拥有可选依赖项?

3.22学习理解httpContext与where 1=1

各个访问限定符的权限范围

访问性模式

如何设置MSSQL数据库访问用户及访问权限