I have a custom user manager class (ASP .NET Identity). I want to override the FindByIdMethod, so that it automatically loads the role names for the user model. This is the only method I am overriding. I am using Microsoft.Identity
nuget packages version 2.2.1, Asp.Net Framework.
However, the code below throws a StackOverflow exception - at await base.FindByIdAsync(userId);
public class MyUserManager : UserManager<MyUser>, IMyUserManager
{
public override async Task<MyUser> FindByIdAsync(string userId)
{
var user = await base.FindByIdAsync(userId);
user.RoleNames = await this.GetRolesAsync(user.Id);
return user;
}
}
When I try similar code without adding 'async' to the overriden signature it works OK - however, I cannot load my role names in this method:
public override Task<MyUser> FindByIdAsync(string userId)
{
var userTask = base.FindByIdAsync(userId); //no errors in this approach
return userTask; //but also no custom behaviour
}
I suspect maybe the IMyUserManager might be problematic, but I need it for the IOC/DI. This was an autogenerated interface, so it has all the public members of the UserManager class.
The user class:
public class MyUser: IdentityUser
{
public string DisplayName { get; set; }
public bool IsActivated { get; set; }
public bool MustChangePassword { get; set; }
public IList<string> RoleNames { get; set; } = new List<string>();
}
Call stack (TelimenaUserManager = MyUserManager, I simplified the name)
UPDATE:
Thanks to Henk's suggestions in the comments, I see that recursion happens in the GetRolesAsync method...
For completeness, I am posting the working code.
I had to cast the current 'IUserStore' to be the 'IUserRoleStore' (Both generic arguments are needed!).
Then get the roles based on the user instance (which avoids the recursion of 'Finding the user')
Thanks @HenkHolterman!