it-swarm.com.de

Liste der Benutzer mit zugewiesenen Rollen in asp.net identity 2.0 abrufen

Ich habe ein Dropdown-Listenfeld, in dem die Rollen aufgeführt sind. Ich möchte die Liste der Benutzer erhalten, die diese Rolle haben. Ich meine eine Liste von Benutzern, die sich in der Rolle "Administrator" oder "CanEdit" befinden. Hier ist mein 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;
}

Bitte helfen.

Aktualisierter Code (noch fehlerhaft)

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;
}

Fehler: Die Select-Methode muss "IQueryable" oder "IEnumerable" oder "Microsoft.AspNet.Identity.EntityFramework.IdentityUser" zurückgeben, wenn ItemType auf "Microsoft.AspNet.Identity.EntityFramework.IdentityUser" gesetzt ist.

Ich habe verschiedene Castings ausprobiert, aber keiner hat geholfen.

UPDATE (Arbeitslösung)

Dank chris544 half mir seine Idee, das Problem zu beheben. Hier ist die Arbeitsmethode: -

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
Abhimanyu

Kein Experte, aber ...

In Identity gab es dafür offensichtlich keine eingebaute Funktionalität, und ich konnte auch nicht von in Roles eingebauten Funktionen arbeiten (es scheint nicht mit anspruchsbasierter Identität zu funktionieren).

Also habe ich so etwas getan:

var users = context.Users        
    .Where(x => x.Roles.Select(y => y.Id).Contains(roleId))
    .ToList();
  • x.Roles.Select(y => y.Id) ruft eine Liste aller Rollen-IDs für user x ab
  • .Contains(roleId) prüft, ob diese Liste von IDs notwendige roleId enthält.
35
chris544

Ich finde die Rolle durch die Eingabe des Rollennamens. Danach finde ich die Liste der Benutzer anhand der ID der Rolle.

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;
}
12
Trieu Doan

Wenn Sie vermeiden möchten, dass der Kontext direkt verwendet wird, können Sie den RoleManager mit dem folgenden Snippet verwenden

roleManager.FindByName("Administrator").Users

oder

roleManager.FindByName("CanEdit").Users

Für eine kurze Diskussion zu diesem Thema schauen Sie sich den diesen Thread an

7
Horizon_Net

Mit dem RoleManager erhalten Sie diese Lösung:

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

Ich würde gerne wissen, ob dies besser oder schlechter war als die anderen Lösungen hier.

4
Rob Church

Es gibt drei Möglichkeiten, dies zu tun. 

Im Controller kann die Rolle des aktuell angemeldeten Benutzers wie folgt überprüft werden: 

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

Außerhalb von Controller können Sie folgendermaßen überprüfen, ob ein bestimmter Benutzer zu einer Rolle gehört:

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

Vergessen Sie nicht, einen Namespace hinzuzufügen,

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

Aus einigen Gründen wie Integrationstests usw. möchten Sie EF direkt verwenden, um die Benutzerrolle wie folgt zu finden:

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
        }

Ich hoffe es hilft. 

Vielen Dank/[email protected]_mode

4
Debug_mode

Entferne den .Email und füge UserName hinzu oder was auch immer zu ASPNetUsers für den Namen hinzugefügt wurde.

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
David Evans

Da solche Bits die Leistung beeinträchtigen, habe ich die anderen hier veröffentlichten Antworten ausprobiert und mir die von ihnen generierte SQL angesehen. Dies scheint der beste Weg zu sein, um alle E-Mail-Adressen des Benutzers aktuell abzurufen.

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));
        }
    }

    ...
}

Die SQL, die es ausführt, wird unten gezeigt:

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
Paul Smith

der Code, der für mich funktionierte, war folgender:

  var users = roleManager.FindByName(roleName).Users.Select(x => x.UserId);
  var usersInRole = Users.Where(u => users.Contains(u.Id));
0
Bartek Wójcik