访问 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的主要内容,如果未能解决你的问题,请参考以下文章