HttpContext
has a scoped lifetime and is dependency injected now. In places where you do not have access to it out of the box (controllers/pages/views), you can inject IHttpContextAccessor
, which is a singleton that knows how to retrieve the HttpContext
instance in scope.
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
could potentially be null, so you need to handle that with a null check.
You will of course need to register MyClass
with the service collection, and you'll need to inject it, as well, when you need it, or none of this will work. Additionally, IHttpContextAccessor
is not included by default, as there's a non-neglible performance impact. You will need to add the following line to your app's ConfigureServices
, if you want to use it:
services.AddHttpContextAccessor();
Now, all that said, pretty much forget everything I just told you. Don't actually do this. A well-designed class should follow the principles of SOLID, one of which is that it should do just one thing and do it well. In the majority of cases, it's completely inappropriate for a class in some library to have knowledge of something like HttpContext
.
Instead, if you need the user id in some method, simply pass it in to that method:
public void DoSomethingWithUserId(string userId)
Then, in your controller, for example, where you already have access to HttpContext
:
myClass.DoSomethingWithUserId(User.FindFirstValue(ClaimTypes.NameIdenfiier));