我已经在Net Core 2.1中构建了REST API
该项目分为程序集:
我可以在模块中正确使用HTTPContext
来下载JWT中保存的UserId
吗?
查询数据库需要查询令牌中有关UserId的信息
我知道,当我在控制器的代码范围内调用时,我将获得正确的值,但是我还将在另一个类中的另一个程序集中获得它的值吗?
查询范围结束时,是否删除了HTTPContext内容?
答案 0 :(得分:2)
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));