【问题标题】:Get list of users with assigned roles in asp.net identity 2.0获取在 asp.net identity 2.0 中分配了角色的用户列表
【发布时间】:2014-05-23 08:27:23
【问题描述】:

我有一个列出角色的下拉列表框。我想获取具有该角色的用户列表。我的意思是“管理员”角色或“CanEdit”角色的用户列表。这是我的代码:

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

请帮忙。

更新的代码(仍然错误)

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

错误:当 ItemType 设置为“Microsoft.AspNet.Identity.EntityFramework.IdentityUser”时,Select 方法必须返回“IQueryable”或“IEnumerable”或“Microsoft.AspNet.Identity.EntityFramework.IdentityUser”之一。

我尝试了各种铸件,但都没有帮助。

更新(工作解决方案)

感谢 chris544,他的想法帮助我解决了这个问题。这是工作方法:-

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

【问题讨论】:

  • 试试 Roles.GetUsersInRole(),你可以得到使用默认 Role Provider API
  • @Larry 你的意思是 [string[] u = Roles.GetUsersInRole(ddlRole)] 或 [_roleManager.Roles.GetUsersInRole(ddlRole)]。首先产生“角色管理器功能尚未启用”错误,其次没有定义“GetUserInRole”。我应该如何使用 Roles.GetUsersInRole()?
  • 您在使用 asp.net mvc 5 吗?我目前正在处理 4. 转到任何操作方法并键入“角色”,它位于“System.Web.Security”命名空间中。
  • 我正在使用 ASP.NET 4.5 和 ASP.NET Identity 2.0

标签: asp.net asp.net-mvc asp.net-mvc-4 asp.net-identity asp.net-identity-2


【解决方案1】:

不是专家,但是...

Identity 中似乎没有内置功能,我也无法从内置角色中获得它(它似乎不适用于基于声明的 Identity)。

所以我最终做了这样的事情:

var users = context.Users        
    .Where(x => x.Roles.Select(y => y.Id).Contains(roleId))
    .ToList();
  • x.Roles.Select(y =&gt; y.Id) 获取 user x 的所有角色 ID 的列表
  • .Contains(roleId) 检查此 id 列表是否包含必要的 roleId

【讨论】:

  • Identity 1.0 中没有内置功能,但在 2.0 中,我在网络上的某个地方看到了这个。
  • 感谢 chris544,您的想法帮助我解决了这个问题。我更新了这个问题,我相信它会对许多开发者有所帮助。
  • 一直在寻找一个小时左右的简单实现。终于找到了。谢谢!
  • 如果角色的Id未知,应该先使用RoleManager的实例。
  • y.Id 应该是 y.RoleId
【解决方案2】:

我通过角色名称输入找到角色。之后,我通过角色的 id 找到列表用户。

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

【讨论】:

  • 很好的答案 Trieu。在我看来,提供了可重用的代码。短小精悍的作品!
  • 我发现@Trieu Doan 在我的情况下不正确,有效的代码如下:` var users = roleManager.FindByName(roleName).Users.Select(x => x.用户身份); var usersInRole = Users.Where(u => users.Contains(u.Id));`
【解决方案3】:

如果你想避免直接使用上下文,你可以使用 RoleManager 和下面的 sn-p

roleManager.FindByName("Administrator").Users

roleManager.FindByName("CanEdit").Users

有关此主题的简短讨论,请查看this thread

【讨论】:

  • 感谢 Horizo​​n_Net..看起来我非常接近解决方案。请检查我更新的产生错误的代码。
  • 这将返回IdentityUserRoles 的集合,而不是ApplicationUsers
【解决方案4】:

您可以通过三种方式做到这一点。

在Controller中当前登录用户的角色可以查看如下,

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

在 Controller 之外,您可以检查特定用户是否属于某个角色,如下所示:

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

不要忘记添加命名空间,

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

由于集成测试等原因,您可能直接想使用EF来查找用户的角色,如下所示:

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
        }

希望对您有所帮助。

谢谢 /dj @debug_mode

【讨论】:

    【解决方案5】:

    使用 RoleManager 可为您提供以下解决方案:

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

    我很想知道这是否比这里的其他解决方案更好或更差。

    【讨论】:

    • 我要做的唯一更改是将上述内容包装在 if 语句中以检查角色是否存在。 if(roleManager.RoleExists("CanEdit")
    • +1 转到 RoleManager(例如角色表)比最终产生大量 SQL 的大量 LINQ 查询要好得多。
    【解决方案6】:

    为我工作的代码如下:

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

    【讨论】:

      【解决方案7】:

      删除.Email 并添加UserName 或添加到ASPNetUsers 的任何名称。

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

      【讨论】:

        【解决方案8】:

        由于这样的位往往会影响性能,我尝试了此处发布的其他答案并查看了它们生成的 SQL。这似乎是目前获取所有用户电子邮件地址的最高效方式。

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

        它执行的SQL如下所示:

        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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-25
          • 2013-10-29
          • 1970-01-01
          • 2014-05-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多