.NET Core 2.1 Удостоверение получить все пользователи со своими связанными ролями - PullRequest
0 голосов
/ 23 июня 2018

Я пытаюсь вытащить всех своих пользователей Identity и связанных с ними ролей на страницу администрирования управления пользователями.Я думал, что это будет достаточно просто, но, видимо, нет.Я попробовал следующее решение: https://stackoverflow.com/a/43562544/5392786, но пока оно не сработало.

Вот что у меня есть:

ApplicationUser:

public class ApplicationUser : IdentityUser
{
    public List<IdentityUserRole<string>> Roles { get; set; }
}

DBContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Идентификационный код запуска

services.AddIdentity<ApplicationUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

БритваСтраница, на которой я хочу отобразить список:

public class IndexModel : PageModel
{
    private readonly UserManager<ApplicationUser> userManager;

    public IndexModel(UserManager<ApplicationUser> userManager)
    {
        this.userManager = userManager;
    }

    public IEnumerable<ApplicationUser> Users { get; set; }

    public void OnGetAsync()
    {
        this.Users = userManager.Users.Include(u => u.Roles).ToList();
    }
}

Я получаю следующую ошибку при вызове userManager.Users.Include(u => u.Roles).ToList();:

MySql.Data.MySqlClient.MySqlException: 'Неизвестный столбец «u.Roles.ApplicationUserId» в «списке полей»

Ответы [ 7 ]

0 голосов
/ 07 июля 2019

работал отлично.Я использую целочисленные ключи, поэтому я заменил «строку» на «int»

ApplicationRole : IdentityRole<int>
ApplicationUserRole : IdentityUserRole<int>
ApplicationUser : IdentityUser<int>

ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, 
IdentityUserClaim<int>,
ApplicationUserRole, IdentityUserLogin<int>, IdentityRoleClaim<int>, 
IdentityUserToken<int>>

Linq: RoleId = (из a в m.UserRoles выберите a.Role.Id) .FirstOrDefault (),

0 голосов
/ 21 июля 2019

Принятый ответ потребовал настройки идентификатора по расширению, что без этого отключит использование roleManager и userManager. При настройке ASP.NET Core Identity больше не следует использовать AddEntityFrameworkStores. Потому что он переопределит все ваши предыдущие настройки и настройки по умолчанию для служб идентификации. Сначала вам нужно создать новые сервисы со следующими подписями: Почему это нарушает ограничение параметра типа 'TUser'?

Без расширения, используя userManager и roleManager:

namespace identityDemo.Controllers
{
    public class UserManagementController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly RoleManager<IdentityRole> _roleManager;
        private readonly UserManager<IdentityUser> _userManager;

            public UserManagementController(ApplicationDbContext context, 
UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            _context = context;
            _roleManager = roleManager; 
            _userManager = userManager; 
        }

        // GET: ApplicationUserRoles
        public async Task<IActionResult> GetApplicationUsersAndRoles()
        {
            return View(new UserMv(
                (from user in await _userManager.Users.ToListAsync()
                 select new UserMv(user, GetUserRoles(user).Result)).ToList()));
        }

        private async Task<List<string>> GetUserRoles(IdentityUser user)
        {
            return new List<string>(await _userManager.GetRolesAsync(user));
        }
}

С простым конструктором для отображения в DTO:

namespace IdentityDemo.Models.ModelView
{
    public class UserMv
    {
public UserMv(IdentityUser aus, List<string> userRoles)
        {
            UserId = aus.Id;
            UserName = aus.UserName;
            RolesHeld = userRoles; 
            Email = aus.Email;
            EmailConfirmed = aus.EmailConfirmed;
            LockoutEnabled = aus.LockoutEnabled;
            AccessFailedCount = aus.AccessFailedCount;
        }
}

и startup.cs

services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
0 голосов
/ 17 апреля 2019

Так как это лучший результат поиска Google;В настоящее время вы можете просто присоединиться к базе данных UserRoles (если ваш контекст базы данных наследуется от IdentityDbContext).

Например, внешнее соединение таблицы ролей с любыми пользовательскими ролями, а затем создание нашего manageUserModel (сокращенная информация о классе applicationUser для нашего API):

var employees = (from bb in _appContext.Users
            join roleIds in _appContext.UserRoles on bb.Id equals roleIds.UserId
            join role in _appContext.Roles on roleIds.RoleId equals role.Id into roles
            orderby bb.LastName, bb.FirstName
            where roles !=null && roles.Any(e => e.Name == Permissions.RoleNames.Administrator || e.Name == Permissions.RoleNames.Employee)
            select ManageUserModel.FromInfo(bb, roles)).ToList();

public static ManageUserModel FromInfo(ApplicationUser info, IEnumerable<UserRole> roles)
    {
        var ret= FromInfo(info);
        ret.Roles = roles.Select(e => new SimpleEntityString() {Id=e.Id, Text=e.Name}).ToList();
        return ret;
    }

Здесь также демонстрируется предложение where, использующее любую информацию о роли (приведенное выше выбирает только пользователей в наших ролях Admin и Employee).

Примечание: этот внутренний элемент присоединяется к IdentityUserRole,так что будут возвращены только пользователи с ролью, если вы хотите, чтобы все пользователи просто добавили «в identRoles» в конец строки roleIds соединения ... и изменили остальные условия соответствующим образом.

0 голосов
/ 05 января 2019

циклически просматривает список пользователей и получает пользовательские роли, вызывая функцию _userManager.GetRolesAsync (user) и просматривая роли пользователя и разделяя роли с помощью "," в одной строковой переменной

[HttpPost]
    public async Task<IActionResult> OnPostGetPagination()
    {


        var users = await _userManager.Users.ToListAsync();
        InputModel inputModel = new InputModel();
        foreach (var v in users)
        {
            inputModel = new InputModel();
            var roles = await _userManager.GetRolesAsync(v);
            inputModel.Email = v.UserName;
            inputModel.role = "";
            foreach (var r in roles)
            {
                if (!inputModel.role.Contains(","))
                {
                    inputModel.role = r;
                }
                else
                {
                    inputModel.role = "," + r;
                }
            }
            Input2.Add(inputModel);
        }


    }

удачи

0 голосов
/ 05 января 2019

Я решил эту проблему, создав представление со всеми необходимыми столбцами (включая роли) и добавив его в контекст.

0 голосов
/ 24 июня 2018

Ссылка комментарий

Первый - это код для получения данных

 public async Task<IEnumerable<AccountViewModel>> GetUserList()
        {
            var userList = await (from user in _context.Users
                                  select new
                                  {
                                      UserId = user.Id,
                                      Username = user.UserName,
                                      user.Email,
                                      user.EmailConfirmed,
                                      RoleNames = (from userRole in user.Roles //[AspNetUserRoles]
                                                   join role in _context.Roles //[AspNetRoles]//
                                                   on userRole.RoleId
                                                   equals role.Id
                                                   select role.Name).ToList()
                                  }).ToListAsync();

            var userListVm = userList.Select(p => new AccountViewModel
            {
                UserId = p.UserId,
                UserName = p.Username,
                Email = p.Email,
                Roles = string.Join(",", p.RoleNames),
                EmailConfirmed = p.EmailConfirmed.ToString()
            });

            return userListVm;
        }

В ядре ASP.Net 2.1 мы настраиваем ApplicationRole таким образом, чтобы получить ролипользователей.Вам нужно определить данные, которые вы хотите явно предоставить пользователю для использования

public class ApplicationRole : IdentityRole
    {
        public virtual ICollection<IdentityUserRole<string>> Users { get; set; }

        public virtual ICollection<IdentityRoleClaim<string>> Claims { get; set; }
    }

Наконец

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            {
                relationship.DeleteBehavior = DeleteBehavior.Restrict;
            }

            modelBuilder.Entity<User>().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
            modelBuilder.Entity<User>().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);

            modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
            modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);

            modelBuilder.EnableAutoHistory(null);
        }

Результатом будут имя пользователя и роли пользователя.Если у пользователя более 1 роли, данные будут отображаться в виде администратора, редактора и т. Д. *

Полный код можно найти здесь здесь здесь и здесь Надеюсь, эта помощь.

0 голосов
/ 24 июня 2018

Я реализовал следующее решение.

Как отмечалось в комментариях CodeNotFound, у IdentityUser было свойство Roles. Это больше не относится к .NET Core. Эта комментарий / проблема на GitHub, кажется, является текущим решением для .Net Core. Я попытался реализовать это с помощью следующего кода:

ApplicationUser

public class ApplicationUser : IdentityUser
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

ApplicationUserRole

public class ApplicationUserRole : IdentityUserRole<string>
{
    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
}

ApplicationRole

public class ApplicationRole : IdentityRole
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

DbContext

public class ApplicationDbContext
    : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
    ApplicationUserRole, IdentityUserLogin<string>,
    IdentityRoleClaim<string>, IdentityUserToken<string>>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<ApplicationUserRole>(userRole =>
        {
            userRole.HasKey(ur => new { ur.UserId, ur.RoleId });

            userRole.HasOne(ur => ur.Role)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();

            userRole.HasOne(ur => ur.User)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();
        });
    }
}

Startup

services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

Наконец, убедитесь, что когда вы используете его, вы с нетерпением загружаете UserRoles пользователя, а затем его роль следующим образом:

this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();

У меня была проблема, когда свойство Role каждого UserRole было нулевым, и это было решено добавлением в .ThenInclude(ur => ur.Role) part.

Документ Microsoft о многоуровневой активной загрузке: https://docs.microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels

Обновление ASP Core 2.2

Присущий от IdentityUserRole<Guid> не строка Вам также может понадобиться удалить код из ModelBuilder, чтобы начать миграцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...