I need access User.Claims with in separate class and inside a static method in asp.net core.Is there any solution.
User?.Claims?.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value
I need access User.Claims with in separate class and inside a static method in asp.net core.Is there any solution.
User?.Claims?.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value
You should pass an instance of IHttpContextAccessor to your static method or class, either through dependency injection or directly.
Make sure to register the accessor as a singleton:
services.AddHttpContextAccessor();
From there on, you can access accessor.HttpContext.User.
public class BLLBaseClass
{
private IHttpContextAccessor httpContextAccessor;
public BLLBaseClass(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public int UserId
{
get
{
var value = httpContextAccessor.HttpContext.User?.Claims?.First(c => c.Type == "UserId").Value;
if (Int32.TryParse(value, out int userId))
{
return userId;
}
return 0;
}
}
}
Inherit that class and you can access directly userid
public class GeneralBLL : BLLBaseClass
{
private readonly GeneralDAL _generalDal;
public GeneralBLL(GeneralDAL generalDal, IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_generalDal = generalDal;
}
public List<Department> GetDepartments()
{
var userId = UserId;
try
{
return _generalDal.GetDepartments();
}
catch (Exception)
{
throw new Exception("unable to get departments.");
}
}
}
In your startup.cs file you need to register the service first by adding the following
services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddSingleton<TestClass>();
Then you should register your class where you want to access the claims from so that we can inject IActionContextAcessor into.
public class TestClass
{
private IActionContextAccessor actionContextAccessor;
public Test(IActionContextAccessor actionContextAccessor)
{
this.actionContextAccessor = actionContextAccessor;
}
public void GetClaims()
{
var claims = actionContextAccessor.ActionContext.HttpContext.User.Claims;
return claims;
}
}
Now you can inject this class anywhere you want to access the users claims. Of course you can also just inject IActionContextAccessor into any class as well if you just simply need to get the claims.
So inside the constructor of your class for example you can say
public class MyCustomClass
{
private TestClass testClass;
public MyCustomClass(TestClass testClass)
{
this.testClass = testClass;
}
public void MyMethod()
{
var usersClaims = this.testClass.GetClaims();
}
}
Hope that helps SoS
I would stronlgy advise staying away from static class implementation for accessing HttpContext.
When you need user identifier in your classes just inject IHttpContextAccessor
public class CustomService
{
private IHttpContextAccessor httpContextAccessor;
public CustomService(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public void CustomMethod()
{
var userId = this.httpContextAccessor.GetUserId();
// do what you want with user identifier
}
}
For this code to work you'll need extension method
public static class HttpContextAccessorExtensions
{
public static int GetUserId(this IHttpContextAccessor httpContextAccessor)
{
var value = httpContextAccessor.HttpContext.User?.Claims?.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value;
if (Int32.TryParse(value, out int userId))
{
return userId;
}
return 0; // or whatever you want if userId is not found (I would suggest making return type int? and returning null here)
}
}
Also you'll need to add this to your Startup.cs inside ConfigureServices method
services.AddHttpContextAccessor();