如何在ASP.NET MVC 5中列出具有角色名称的用户

我有ASP.NET MVC 5网站的默认项目模板,我试图列出具有角色名称(而不是ID)的所有用户。

查询是:

db.Users.Include(u => u.Roles).ToList() 

然后我想用以下内容打印角色名称:

 @string.Join(", ", user.Roles.Select(r => r.RoleId)) 

问题是我只能访问RoleId ,而不能访问存储Name和其他属性的Role类。

我可以运行另一个select来获取所有角色,然后将其用作查找。 或直接在查询中写一个连接? 我不确定如何,因为我无法访问具有绑定用户和角色的IdentityUserRole实体的表。

问题的根源似乎是IdentityUserRole (不是Role )的Roles集合, RoleId包含RoleIdUserId

 public class IdentityUserRole { public virtual TKey RoleId { get; set; } public virtual TKey UserId { get; set; } } 

我认为如果想在EF中建立N对N关系,他们应该直接收集Roles ,然后重写OnModelCreating并指定关系。 这种方法似乎使从一个对象浏览对象变得复杂。

为什么他们决定将IdentityUserRole作为额外实体包含在内? 能够在关系中添加额外数据吗? 代价是无法从用户导航到角色?

我这样做的方式是:

 using (var userManager = new UserManager(new UserStore(new ApplicationContext())) { var rolesForUser = await userManager.GetRolesAsync(userId); // rolesForUser now has a list role classes. } 

身份团队制作了两个管理员: RoleManager用于排序角色(尽管不是用户角色)和UserManager基本上用于所有身份validation。 还有一个SignInManager ,但不需要。

因此, UserManager找到用户,创建用户,删除用户,发送电子邮件….列表继续。

所以我的Action看起来像这样:

  public async Task GetRolesForUser(string userId) { using ( var userManager = new UserManager(new UserStore(new ApplicationDbContext()))) { var rolesForUser = await userManager.GetRolesAsync(userId); return this.View(rolesForUser); } } 

要执行原始SQL,您可以执行以下操作:

根据查询的输出创建Entity Framework可以映射到的类:

 public class UserWithRole { public string UserName {get;set;} // You can alias the SQL output to give these better names public string Name {get;set;} } using (var context = new DbContext()) { var sql = @" SELECT AspNetUsers.UserName, AspNetRoles.Name FROM AspNetUsers LEFT JOIN AspNetUserRoles ON AspNetUserRoles.UserId = AspNetUsers.Id LEFT JOIN AspNetRoles ON AspNetRoles.Id = AspNetUserRoles.RoleId WHERE AspNetUsers.Id = @Id"; var idParam = new SqlParameter("Id", theUserId); var result = context.Database.ExecuteQuery(sql, idParam); } 

很简单!

如果为SQL返回列添加别名:

 SELECT AspNetUSers.UserName, AspNetRoles.Name As RoleName 

然后你的DTO类看起来像这样:

 public class UserWithRole { public string UserName {get;set;} public string RoleName {get;set;} } 

这显然更清洁了。

这就是我使用MVC 5,Identity 2.0以及John Atten描述的自定义用户和角色的方法

在控制器中

 public virtual ActionResult ListUser() { var users = UserManager.Users; var roles = new List(); foreach (var user in users) { string str = ""; foreach (var role in UserManager.GetRoles(user.Id)) { str = (str == "") ? role.ToString() : str + " - " + role.ToString(); } roles.Add(str); } var model = new ListUserViewModel() { users = users.ToList(), roles = roles.ToList() }; return View(model); } 

在ViewModel中

 public class ListUserViewModel { public IList users { get; set; } public IList roles { get; set; } } 

在我看来

 @{ int i = 0; } @foreach (var item in Model.users) { @Html.DisplayFor(modelItem => item.Name) [... Use all the properties and formating you want ... and ] @Model.roles[i] i++; } 

我认为从C#应用程序执行动态SQL是一种糟糕的技术。 以下是我的方法:

模型:

  public class ApplicationRole : IdentityRole { public ApplicationRole() : base() { } public ApplicationRole(string name) : base(name) { } public string Description { get; set; } } 

控制器:

 using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.AspNet.Identity.EntityFramework; using System.Linq; using System.Net; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Collections.Generic; //Example for Details. if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } var role = await RoleManager.FindByIdAsync(id); // Get the list of Users in this Role var users = new List(); // Get the list of Users in this Role foreach (var user in UserManager.Users.ToList()) { if (await UserManager.IsInRoleAsync(user.Id, role.Name)) { users.Add(user); } } ViewBag.Users = users; ViewBag.UserCount = users.Count(); return View(role); 

查看(使用ApplicationRole)

  

Roles.


@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)
@Html.DisplayNameFor(model => model.Description)
@Html.DisplayFor(model => model.Description)

List of users in this role

@if (ViewBag.UserCount == 0) {

No users found in this role.

} @foreach (var item in ViewBag.Users) { }
@item.UserName
 using System.Linq; using System.Data; using System.Data.Entity; var db = new ApplicationDbContext(); var Users = db.Users.Include(u => u.Roles); foreach (var item in Users) { string UserName = item.UserName; string Roles = string.Join(",", item.Roles.Select(r=>r.RoleId).ToList()); } 

感谢@Callum Linington的回答。 试着让像我这样的初学者有点清楚。 以下是获取具有角色的用户列表的步骤。

1-创建一个名为“UsersWithRoles”的视图模型,其中包含一些属性,如下所示:

在此处输入图像描述

2-创建一个名为“RolesController”的控制器,然后在其中添加以下代码。

  public ActionResult Index() { using (var context = new ApplicationDbContext()) { var sql = @" SELECT AspNetUsers.UserName, AspNetRoles.Name As Role FROM AspNetUsers LEFT JOIN AspNetUserRoles ON AspNetUserRoles.UserId = AspNetUsers.Id LEFT JOIN AspNetRoles ON AspNetRoles.Id = AspNetUserRoles.RoleId"; //WHERE AspNetUsers.Id = @Id"; //var idParam = new SqlParameter("Id", theUserId); var result = context.Database.SqlQuery(sql).ToList(); return View(result); } } 

这是RolesController的样子:

在此处输入图像描述

3-将Index页面添加到Roles文件夹,并在其中添加以下代码。

 @model IEnumerable 

Users

@foreach (var user in Model) { }
User Name Role
@user.UserName @user.Role