首页 > 解决方案 > 如何从 Asp.net Core Razor 页面中的 IdentityUser 列表中获取没有角色的用户

问题描述

我创建并植入了两个角色(管理员、经理),并添加了从角色中删除用户并通过设计用户表来添加它们的选项。但我想要用户未添加到任何角色的用户列表。

我尝试!在方法中使用逻辑否定运算符()GetUsersInRoleAsync,它的说法不能应用于identityuser类型列表。有没有什么方法可以获取没有添加角色的唯一用户(成员)列表?

标签: c#asp.net-coreidentityrazor-pages

解决方案


你要问数据库的是,哪些用户没有分配任何角色?

您可以首先将 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;
}

你去吧。现在,如果您稍微修改此代码以适合您的项目,您应该有一种方法可以找到所有不属于任何角色的用户。


推荐阅读