2

Я пытаюсь настроить авторизацию на основе ролей в ASP.NET Identity. Я хочу сделать так, чтобы пользователи Admin могли видеть список пользователей и их роли (на странице Index) и изменять роли отдельных пользователей (на странице редактирования).Просмотр ролей пользователя показывает идентификатор роли вместо имени роли

Вот мой контекст:

modelBuilder.Entity<IdentityUser>() 
    .HasKey<string>(k => k.Id) 
    .ToTable("Users"); 
modelBuilder.Entity<IdentityUserRole>() 
    .HasKey(r => new { r.RoleId, r.UserId }) 
    .ToTable("UserRoles"); 
modelBuilder.Entity<IdentityUserLogin>() 
    .HasKey<string>(f => f.UserId) 
    .ToTable("UserLogins"); 
modelBuilder.Entity<IdentityRole>() 
    .ToTable("Roles"); 

Мой индекс действия в UsersController.cs:

public ActionResult Index() 
    { 
     return View(db.Users.Include(i => i.Roles).ToList()); 
    } 

Индексный:

@model List<Microsoft.AspNet.Identity.EntityFramework.IdentityUser> 

//stuff 

    @foreach (var item in Model) 
    { 
     <tr class="index-item" data-href="@Url.Action("Details", "Users", new { id=item.Id })"> 
      <td> 
       @Html.DisplayFor(modelItem => item.Email) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Roles)"> 
      </td> 
      <td class="index-links"> 
       //stuff 
      </td> 
     </tr> 
    } 
</table> 

Мой Роли таблице:

Roles table

Мои UserRoles стол:

UserRoles Table

На основе этих таблиц, пользователь имеет роль "Viewer". Однако, вместо того чтобы показывать имя роли, вид показывает Role ID:

index view

Как мне сделать это показать имя Role вместо (в данном случае «просмотра»)?

ответ

4

IdentityUserRole класса не имеют навигационных свойств IdentityUser и IdentityRole, просто UserId и RoleId, его не так легко получить роли пользователя. Таким образом, мы должны использовать 2 дБ вызывает

var users = db.Users.Include(u => u.Roles); 
var roles = db.Roles.Include(r => r.Users); 

А ViewModel как этот

public class UsersRolesViewModel 
{ 
    public List<ApplicationUser> Users { set; get; } 
    public List<IdentityRole> Roles { set; get; } 
} 

и в View

@foreach (var user in Model.Users) 
{ 
    <tr class="index-item" data-href="@Url.Action("Details", "Users", new { id= user.Id })"> 
     <td> 
      @user.Email 
     </td> 
     <td> 
      @string.Join(",", roles.Where(r => r.Users.Any(u => u.UserId == user.Id)).Select(r => r.Name)) 
     </td> 
     <td class="index-links"> 
       //stuff 
     </td> 
    </tr> 
} 

Редактировать

Вы можете получить все данные вы хотите получить один запрос

var users = (from u in db.Users 
      let query = (from ur in db.Set<IdentityUserRole>() 
          where ur.UserId.Equals(u.Id) 
          join r in db.Roles on ur.RoleId equals r.Id select r.Name) 
          select new UserDto() {User = u, Roles = query.ToList<string>()}) 
         .ToList(); 

Используя эту простую модель

public class UserDto 
{ 
    public ApplicationUser User { set; get; } 
    public List<string> Roles { set; get; } 
} 

и тому в View

@foreach (var user in Model.Users) 
    { 
     var appUser = user.ApplicationUser; 
     var roles = user.Roles; 

     <tr class="index-item" data-href="@Url.Action("Details", "Users", new { id= appUser.Id })"> 
      <td> 
       @appUser.Email 
      </td> 
      <td> 
       @string.Join(",", roles) 
      </td> 
      <td class="index-links"> 
        //stuff 
      </td> 
     </tr> 
    } 
+0

Да, я в конечном итоге делает что-то вдоль этих линий. Я отвечу на ваш ответ. –

+1

@EgeErsoz улучшенный ответ – tmg

+1

Raely хороший путь! –

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