NetDev
NetDev

Reputation: 107

Access to HTTPContext

I have built REST API in Net Core 2.1

The project is divided into Assemblies:

Can I use HTTPContext correctly in the modules to download the saved UserId in JWT?

The query for the database requires information about UserId in the token on the query

I know that when I call in the scope of the controller's code I will get the correct value but will I also get it in another assembly in a different class?

When the scope of the query ends, is the HTTPContext content removed?

Upvotes: 0

Views: 619

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239200

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));

Upvotes: 2

Related Questions