Я экспериментировал с новым MVC 5, у меня есть несколько моделей, контроллер и настройка представлений с использованием первых миграций кода.
У меня вопрос: как набрать пользователей и роли? В настоящее время я загружаю некоторые справочные данные в свой метод Seed в Configuration.cs. Но мне кажется, что таблицы пользователей и ролей не создаются, пока что-то сначала не попадет в AccountController.
В настоящее время у меня есть две строки подключения, поэтому я могу разделить свои данные из моей аутентификации в разные базы данных.
Как я могу заполнить таблицы пользователей, ролей и т. Д. Вместе с другими? А не при попадании в контроллер аккаунта?
Ответы:
Вот пример обычного подхода Seed:
protected override void Seed(SecurityModule.DataContexts.IdentityDb context) { if (!context.Roles.Any(r => r.Name == "AppAdmin")) { var store = new RoleStore<IdentityRole>(context); var manager = new RoleManager<IdentityRole>(store); var role = new IdentityRole { Name = "AppAdmin" }; manager.Create(role); } if (!context.Users.Any(u => u.UserName == "founder")) { var store = new UserStore<ApplicationUser>(context); var manager = new UserManager<ApplicationUser>(store); var user = new ApplicationUser {UserName = "founder"}; manager.Create(user, "ChangeItAsap!"); manager.AddToRole(user.Id, "AppAdmin"); } }
Я использовал пакетный менеджер "update-database". БД и все таблицы были созданы и заполнены данными.
источник
context.Users.Add(user);
междуmanager.Create(user, "ChangeItAsap!");
иmanager.AddToRole(user.Id, "AppAdmin");
. Итак, у новорожденного пользователя нет User.Id.Это небольшое дополнение, но для всех, у кого есть «UserId not found». сообщение при попытке посеять: (Том Риган задавал этот вопрос в комментариях, и я сам на какое-то время застрял на нем)
Это означает, что manager.Create (пользователь, «ChangeItAsap!») Не удалось. У этого могла быть другая причина, но для меня это было потому, что мой пароль не прошел проверку.
У меня был специальный валидатор паролей, который не вызывался при заполнении базы данных, поэтому правила проверки, которые я использовал (minlength 4 вместо 6 по умолчанию), не применялись. Убедитесь, что ваш пароль (и все остальные поля в этом отношении) проходят проверку.
источник
IdentityResult result = manager.Create(user, "ChangeItAsap!"); if (result.Succeeded == false) { throw new Exception(result.Errors.First()); }
Это моя основа метода на ответе Валина, я добавил роли в db и добавил пароль для пользователя. Этот код помещается в
Seed()
метод в Migrations> Configurations.cs.// role (Const.getRoles() return string[] whit all roles) var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context)); for (int i = 0; i < Const.getRoles().Length; i++) { if (RoleManager.RoleExists(Const.getRoles()[i]) == false) { RoleManager.Create(new IdentityRole(Const.getRoles()[i])); } } // user var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); var PasswordHash = new PasswordHasher(); if (!context.Users.Any(u => u.UserName == "admin@admin.net")) { var user = new ApplicationUser { UserName = "admin@admin.net", Email = "admin@admin.net", PasswordHash = PasswordHash.HashPassword("123456") }; UserManager.Create(user); UserManager.AddToRole(user.Id, Const.getRoles()[0]); }
источник
Здесь у меня очень простое, чистое и гладкое решение.
protected override void Seed(UserContext context) { //Step 1 Create the user. var passwordHasher = new PasswordHasher(); var user = new IdentityUser("Administrator"); user.PasswordHash = passwordHasher.HashPassword("Admin12345"); user.SecurityStamp = Guid.NewGuid().ToString(); //Step 2 Create and add the new Role. var roleToChoose = new IdentityRole("Admin"); context.Roles.Add(roleToChoose); //Step 3 Create a role for a user var role = new IdentityUserRole(); role.RoleId = roleToChoose.Id; role.UserId = user.Id; //Step 4 Add the role row and add the user to DB) user.Roles.Add(role); context.Users.Add(user); }
источник
protected override void Seed(ApplicationDbContext context) { SeedAsync(context).GetAwaiter().GetResult(); } private async Task SeedAsync(ApplicationDbContext context) { var userManager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context)); var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole, int, ApplicationUserRole>(context)); if (!roleManager.Roles.Any()) { await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AdminRoleName }); await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AffiliateRoleName }); } if (!userManager.Users.Any(u => u.UserName == "shimmy")) { var user = new ApplicationUser { UserName = "shimmy", Email = "shimmy@gmail.com", EmailConfirmed = true, PhoneNumber = "0123456789", PhoneNumberConfirmed = true }; await userManager.CreateAsync(user, "****"); await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName); } }
источник
Task.Run(async () => { await SeedAsync(context); }).Wait();
. Лучше написать,SeedAsync(context).GetAwait().GetResult();
что немного лучше.Похоже, они меняют способ работы аутентификации в MVC5, изменили мой Global.asax.cs на следующее: помогло!
using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using System.Threading.Tasks; using MvcAuth.Models; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using System.Threading; using Microsoft.AspNet.Identity.EntityFramework; namespace MvcAuth { public class MvcApplication : System.Web.HttpApplication { async Task<bool> AddRoleAndUser() { AuthenticationIdentityManager IdentityManager = new AuthenticationIdentityManager( new IdentityStore(new ApplicationDbContext())); var role = new Role("Role1"); IdentityResult result = await IdentityManager.Roles.CreateRoleAsync(role, CancellationToken.None); if (result.Success == false) return false; var user = new ApplicationUser() { UserName = "user1" }; result = await IdentityManager.Users.CreateLocalUserAsync(user, "Password1"); if (result.Success == false) return false; result = await IdentityManager.Roles.AddUserToRoleAsync(user.Id, role.Id, CancellationToken.None); return result.Success; } protected async void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); bool x = await AddRoleAndUser(); } } }
источник
напишите этот код в своей конфигурации миграции.
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext> { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = false; } protected override void Seed(ApplicationDbContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. context.Roles.AddOrUpdate(p => p.Id, new IdentityRole { Name = "Admins"}, new IdentityRole { Name = "PowerUsers" }, new IdentityRole { Name = "Users" }, new IdentityRole { Name = "Anonymous" } ); } }
источник