Obtenir la liste des utilisateurs avec des rôles dans asp.net identité 2.0

j'ai une liste déroulante qui répertorie les rôles. Je veux obtenir la liste des utilisateurs ayant ce rôle. Je veux dire la liste des utilisateurs qui sont dans le rôle "Administrateur" ou "CanEdit". Voici mon code:

public IQueryable<Microsoft.AspNet.Identity.EntityFramework.IdentityUser> 
  GetRolesToUsers([Control] string ddlRole)
{    
  //ddlRole returns role Id, based on this Id I want to list users

  var _db = new ApplicationDbContext();
  IQueryable<Microsoft.AspNet.Identity.EntityFramework.IdentityUser> query = _db.Users;

  if (ddlRole != null)
  {
    //query = query.Where(e => e.Claims == ddlRole.Value);  ???????              
  }

  return query;
}

Aidez-moi.

mise à Jour du Code (encore une erreur)

public List<IdentityUserRole> GetRolesToUsers([Control]string ddlRole)
{

  var roleManager = 
   new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
  var users = roleManager.FindByName("Administrator").Users.ToList();
  return users;
}
Erreur

: la méthode Select doit renvoyer l'une des méthodes" IQueryable "ou" IEnumerable " ou "Microsoft.AspNet.Identité.EntityFramework.IdentityUser" quand ItemType est réglé sur "Microsoft.AspNet.Identité.EntityFramework.IdentityUser".

j'ai essayé plusieurs moulages mais aucun d'eux n'a aidé.

mise à JOUR (solution de travail)

grâce à chris544, son idée m'a aidé à arranger ça. Voici la méthode de travail: -

public List<ApplicationUser> GetRolesToUsers([Control]string ddlRole)
{
  var context = new ApplicationDbContext();
  var users =
    context.Users.Where(x => x.Roles.Select(y => y.RoleId).Contains(ddlRole)).ToList();

  return users;
}
26
demandé sur Shimmy 2014-05-23 12:27:23

8 réponses

pas un expert, mais ...

il ne semblait pas y avoir de construit dans la funcionality pour ceci dans L'identité et je ne pouvais pas obtenir le travail de construit dans les rôles aussi (il semble ne pas fonctionner avec l'identité fondée sur les revendications).

alors j'ai fini par faire quelque chose comme ça:

var users = context.Users        
    .Where(x => x.Roles.Select(y => y.Id).Contains(roleId))
    .ToList();
  • x.Roles.Select(y => y.Id) obtient une liste de tous les identificateurs de rôle pour user x
  • .Contains(roleId) vérifie si cette liste d'id contient nécessaire roleId
34
répondu chris544 2017-10-03 09:29:08

je trouve le rôle par le nom de rôle entré. Après, je trouve des utilisateurs de liste par id du rôle.

public List<ApplicationUser> GetUsersInRole(string roleName)
{
 var roleManager = 
  new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new  ApplicationDbContext()));
 var role = roleManager.FindByName(roleName).Users.First();
 var usersInRole = 
  Users.Where(u => u.Roles.Select(r => r.RoleId).Contains(role.RoleId)).ToList();
 return usersInRole;
}
11
répondu Trieu Doan 2017-12-02 18:46:18

si vous voulez éviter d'utiliser le contexte directement, Vous pouvez utiliser le RoleManager avec l'extrait suivant

roleManager.FindByName("Administrator").Users

ou

roleManager.FindByName("CanEdit").Users

pour une brève discussion sur ce sujet, consultez le ce fil de discussion

7
répondu Horizon_Net 2017-05-23 10:31:00

il y a trois façons de le faire.

dans le contrôleur courant connecté dans le rôle de l'utilisateur peut être vérifié comme suit,

  if(User.IsInRole("SysAdmin"))
        {

contrôleur extérieur vous pouvez vérifier si un utilisateur particulier appartient à un rôle comme suit:

 ApplicationUserManager UserManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var roles = UserManager.GetRoles(userid);
        if (roles.Contains("SysAdmin"))
        {
        }

n'oubliez pas d'ajouter namespace,

using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

pour certaines raisons telles que les tests d'intégration, etc, Vous pouvez directement utiliser EF pour trouver les rôle de la façon suivante:

string userId = User.Identity.GetUserId();
        ApplicationDbContext db = new ApplicationDbContext();
        var role = (from r in db.Roles where r.Name.Contains("Admin") select r).FirstOrDefault();
        var users = db.Users.Where(x => x.Roles.Select(y => y.RoleId).Contains(role.Id)).ToList();
        if (users.Find(x => x.Id == userId) != null)
        {
            // User is in the Admin Role
        }

J'espère que ça aidera.

Merci / dj @le mode de débogage

4
répondu Debug_mode 2014-10-28 20:20:17

en utilisant le RoleManager vous donne cette solution:

if(roleManager.RoleExists("CanEdit"))
{
    var idsWithPermission = roleManager.FindByName("CanEdit").Users.Select(iur => iur.Id);
    var users = db.Users.Where(u => idsWithPermission.Contains(u.Id));
}

j'aimerais savoir si c'est mieux ou pire que les autres solutions ici.

4
répondu Rob Church 2015-04-17 18:03:57

le code qui travaillait pour moi était le suivant:

  var users = roleManager.FindByName(roleName).Users.Select(x => x.UserId);
  var usersInRole = Users.Where(u => users.Contains(u.Id));
0
répondu Bartek Wójcik 2016-10-29 15:33:09

supprimer le .Email et ajouter UserName ou ce qui a été ajouté au ASPNetUsers pour nom.

private void AddAddminToMail(MailMessage message)
{
    var roles = db.Roles.Include(m => m.Users).Where(m => m.Name == "Admin").First();
    foreach (var user in roles.Users)
        {
            var id = user.UserId;
            var userEmail = db.Users.Find(id).Email;
            message.To.Add(userEmail);
        }      
}
0
répondu David Evans 2017-02-28 13:48:51

puisque les bits comme celui-ci ont tendance à affecter la performance, j'ai essayé les autres réponses postées ici et regardé le SQL qu'ils ont généré. Cela semble être la façon la plus performante d'obtenir toutes les adresses e-mail de l'utilisateur actuellement.

public void SendEmailToUsersInRole(string roleName)
{
    MailMessage message = new MailMessage();
    ...

    using (var usersDB = new ApplicationDbContext())
    {
        var roleId = 
            usersDB.Roles.First(x => x.Name == roleName).Id;

        IQueryable<string> emailQuery =
            usersDB.Users.Where(x => x.Roles.Any(y => y.RoleId == roleId))
                         .Select(x => x.Email);

        foreach (string email in emailQuery)
        {
            message.Bcc.Add(new MailAddress(email));
        }
    }

    ...
}

le SQL qu'il exécute est montré ci-dessous:

SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name]
    FROM [dbo].[AspNetRoles] AS [Extent1]
    WHERE N'Reviewer' = [Extent1].[Name]

SELECT 
    [Extent1].[Email] AS [Email]
    FROM [dbo].[AspNetUsers] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[AspNetUserRoles] AS [Extent2]
        WHERE ([Extent1].[Id] = [Extent2].[UserId]) AND ([Extent2].[RoleId] = @p__linq__0)
    )


-- p__linq__0: '3' (Type = String, Size = 4000)
0
répondu Paul Smith 2018-07-02 19:43:51