0
votes

I use a pretty effective method to list my users in .net core. I wanted to add the name of the role related to the user but I get this error. I have found topics on the subject and resolved the problem but my solution is really not efficient compared to this method.

My question is: is it possible to return the role name this way or am I forced to change my code completely?

Here is my code with error :

List<UserListViewModel> users = new List<UserListViewModel>();

users = _userManager.Users.Select(u => new UserListViewModel
{
     Id = u.Id,
     DateOfCreation = u.DateOfCreation,
     Email = u.Email,
     FullName = u.LastName + " " + u.FirstName,
     IsActive = u.IsActive,
     IsBan = u.IsBan,
     RoleName = _roleManager.Roles.Single(x => x.Name == _userManager.GetRolesAsync(u).Result.SingleOrDefault()).Name


}).ToList();

InvalidOperationException: A second operation started in this context before a previous operation completed. Any instance members are not guaranteed to be thread-safe.

I think the reason is the call of _userManager but I don't know how to make this difference.

EDIT :

Here is the declaration of _userManager

public class UsersController : Controller
{
    private readonly ApplicationDbContext _context;
    private readonly RoleManager<ApplicationRole> _roleManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public UsersController(UserManager<ApplicationUser> userManager, ApplicationDbContext context, RoleManager<ApplicationRole> roleManager)
    {
        _context = context;
        _roleManager = roleManager;
        _userManager = userManager;
    }

EDIT 2 :

When I use a using for _userManager I have an other error. It told me :

Cannot create a DbSet for 'IdentityRole' because this type is not included in the model for the context.

using (var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(_context), null, null, null, null, null, null, null, null))
            { 
                users = um.Users.Select(u => new UserListViewModel
                {
                    Id = u.Id,
                    DateOfCreation = u.DateOfCreation,
                    Email = u.Email,
                    FullName = u.LastName + " " + u.FirstName,
                    IsActive = u.IsActive,
                    IsBan = u.IsBan,
                    RoleName = _roleManager.Roles.Single(x => x.Name == um.GetRolesAsync(u).Result.SingleOrDefault()).Name
                }).ToList();
            }

I wonder if the declaration of new userManager is good. Someone know something about that ?

Sorry if my English isn't perfect.

Thank you,

Regards,

1
Please show us how _userManager is declared and set. - mjwills
Hello, I Edit my post to show you the _serManager declaration. Did you think I really need o use a using context ? I'll try this and back to you. Thanks - cmuller
May I don't understand the linked post but I use injection with startup.cs . I'm not sure, but I don't think this post really help me. - cmuller

1 Answers

0
votes

when I use a User Manager I have the constructor and a public property in the class as following:

public AccountController
        (
            XUserManager userManager,
            XSignInManager signInManager,
            IDataService svc
        )
    {
        UserManager = userManager;
        SignInManager = signInManager;
        _svc = svc;
    }


public XUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<XUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

This ensures I am using the same instance. Could it be that a new instance is being created for you when you call GetRolesAsync?