【发布时间】:2017-06-11 01:06:42
【问题描述】:
我正在尝试从我的 Web API 中的控制器外部的上下文中获取当前用户。我正在使用 OpenIddict 对用户进行身份验证,因此授权是通过令牌进行的。
我已在我的 Startup.cs 中将 HttpContextAcessor 注册为单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
之后,我将 HttpContexrAcessor 注入到我的集线器中,如下所示:
public class NotificationHub : Hub
{
private IHttpContextAccessor _contextAccessor;
private HttpContext _context { get { return _contextAccessor.HttpContext; } }
public NotificationHub(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public async Task JoinGroup()
{
Groups.Add(Context.ConnectionId, $"notification_{_context.User.Identity.Name}");
}
public void Send(JsonResult notification)
{
Clients.Client(Context.ConnectionId).sendNotification(notification);
}
}
问题在于 _context.User.Identity.Name 始终为空。
有没有办法做到这一点?
【问题讨论】:
-
在请求管道之外访问 HttpContext 是灾难的根源。如果你的班级需要
User.Identity.Name,那么用传入的数据构造它。如果您在构建类时无法访问User.Identity.Name之类的内容,那么无论如何您都不太可能访问类中的静态HttpContext。 -
@ChrisPratt 问题是我需要将用户映射到集线器的 ConnectionID 或将用户插入集线器的组中,其中用户将是唯一的成员。在通知的情况下,它将使用 HubContext 从控制器发送,因此我只需将其发送给一个用户。
-
如果你从控制器发送它,那么你有机会在那个时候传递用户。与存在的活动用户进行交互更合适。如果您的设置不适合这样做,那就是设计问题。
-
@ChrisPratt 是的,但是无法从控制器获取集线器 ConnectionID,因此我无法通过 ConnectionID 发送通知,也无法将用户插入组中,因为它还需要 connectionid完成。
-
再次,设计问题。然后,应该将“Hub ConnectionID”注入到任何需要它的类中。换句话说,你很可能在一个班级中混为一谈。记住 SOLID,类应该封装离散的功能单元(做一件事,并且做好)。需要并非同时可用的依赖项表明您的课程在这方面失败了。
标签: asp.net-mvc asp.net-core asp.net-core-mvc .net-core asp.net-core-webapi