Как получить пользователей без роли из списка IdentityUser в Asp.net Core Razor Pages - PullRequest
0 голосов
/ 20 октября 2019

Я создал и разместил две роли (Администратор, Менеджер) и добавил опции для удаления пользователей из ролей и добавления их, создав таблицу пользователей. Но я хочу список пользователей, в которых пользователи не добавлены ни к каким ролям. Я попытался с (!) Оператором в методе GetUsersInRoleAsync, его высказывание не может быть применено к списку типа identityuser. Есть ли способ получить список только пользователей (участников), где роли не добавлены?

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Отношения пользователей и ролей сохраняются в таблице AspNetUserRoles, поэтому вы можете выполнить запрос, чтобы получить пользователей без какой-либо роли:

var usersWithoutAnyRole = _dbcontext.Users
        .Where(c => !_dbcontext.UserRoles
        .Select(b => b.UserId).Distinct()
        .Contains(c.Id)).ToList();

Введите dbcontext, где вы хотите использовать:

private readonly ApplicationDbContext _dbcontext;


public IndexModel(ApplicationDbContext dbcontext)
{
    _dbcontext = dbcontext;
}
0 голосов
/ 20 октября 2019

Что вы хотите спросить у базы данных, какие пользователи не назначены ни на какие роли?

Вы можете начать с внедрения класса RoleManager в ваш контроллер, так как он предоставляет свойство с именем roles, который мы хотим использовать. Нам также нужен UserManager, поэтому мы добавляем его также.

// When you're not using the default IdentityRole and IdentityUser class.. 
// you have to change the all of the types IdentityRole and IdentityUser to match those configured in startup.cs.

private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<IdentityUser> _userManager;

public RoleAdminController(RoleManager<IdentityRole> roleManager, 
                           UserManager<IdentityUser> _userManager) 
{
    _roleManager = roleManager;
    _userManager = userManager;
}

Теперь, используя _roleManager, вы можете сказать _roleManager.Roles, и он возвращает перечисление ролей, которые были определены в вашем приложении.

public async Task<IEnumerable<IdentityRole>> GetRoles() {
    return await _roleManager.Roles;
}

Мы хотим использовать это перечисление ролей для создания списка пользователей, назначенных на любую роль:

public async Task<List<string>> UsersInAnyRole() 
{
    var roles = await GetRoles();
    var usersInAnyRole = new List<string>();

    foreach (var role in roles)
    {
        var usersInRole = await GetUsersAssociatedToRole(role.RoleId);
        if (usersInRole.Count > 0)
        {
            usersInAnyRole.AddRange(usersInRole);
        }
    }

    return usersInAnyRole;
}

public async Task<List<string>> GetUsersAssociatedToRole(string roleId)
{
    var names = new List<string>();
    var role = await _roleManager.FindByIdAsync(roleId);

    if (role != null) 
    {
        foreach (var user in _userManager.Users) 
        {
            if (user != null && await _userManager.IsInRoleAsync(user, role.Name)) 
            {
                names.Add(user.UserName); // Or add user.Id if that works better for your use-case.
            }
        }
    }

    return names;
}

Так что сейчас, после вызова метода UsersInAnyRole (), он будетзапросить базу данных для всех ролей. А затем используйте диспетчер пользователей, чтобы вернуть список пользователей, связанных с этой конкретной ролью.

Поскольку мы делаем это для каждой роли в приложении, мы теперь получаем Список, содержащий всех наших пользователей, которым присвоено любых ролей, связанных с ними. ,Осталось только сравнить их со списком, который содержит все имен пользователей наших пользователей, и сравнить со списком пользователей, которые находятся в ролях, чтобы получить список, содержащий все имена пользователей, которые былиотсутствует в нашем списке usersInAnyRole.

Таким образом, мы можем создать еще два метода, один для извлечения всех имен пользователей и другой для фильтрации пользователей, которые имеют роли.

public async Task<List<string>> GetAllUserNames()
{
    return await _userManager.Users.Select(user => user.UserName).ToList();
}

// Let's tie it all together.
public async Task<List<string>> UsersWithoutRoles()
{
    var usersInRoles = await UsersInAnyRole();

    var allUserNames = await GetAllUserNames();

    var usersNotInRole = allUserNames.Where(user => !usersInRoles.Any(userInRole => userInRole == user)

    return usersNotInRole;
}

И тамВаш ход. Теперь, если вы немного измените этот код в соответствии с вашим проектом, у вас должен быть способ найти всех пользователей, которые не имеют никакой роли.

...