Bawiłem się nowym MVC 5, mam kilka modeli, konfiguracji kontrolera i widoków przy użyciu migracji najpierw kodu.
Moje pytanie brzmi: jak zasiać użytkowników i role? Obecnie umieszczam pewne dane referencyjne w mojej metodzie Seed w Configuration.cs. Ale wydaje mi się, że tabele użytkowników i ról nie są tworzone, dopóki coś nie trafi do AccountController.
Obecnie mam dwa parametry połączenia, więc mogę oddzielić moje dane z mojego uwierzytelnienia do różnych baz danych.
Jak mogę sprawić, by tabele użytkowników, ról itp. Zapełniły się razem z innymi? A nie po trafieniu w kontroler konta?
asp.net-mvc
asp.net-mvc-5
ef-migrations
seeding
MrBeanzy
źródło
źródło
Odpowiedzi:
Oto przykład zwykłego podejścia do nasion:
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"); } }
Użyłem menedżera pakietów "update-database". Baza danych i wszystkie tabele zostały utworzone i wypełnione danymi.
źródło
context.Users.Add(user);
międzymanager.Create(user, "ChangeItAsap!");
amanager.AddToRole(user.Id, "AppAdmin");
. Tak więc nowonarodzony użytkownik nie ma User.Id.To niewielki dodatek, ale dla każdego, kto ma „UserId not found”. wiadomość przy próbie seedowania: (Tom Regan miał to pytanie w komentarzach i sam na to utknąłem)
Oznacza to, że manager.Create (użytkownik, "ChangeItAsap!") Nie powiodło się. Może to mieć inny powód, ale dla mnie było to spowodowane tym, że moje hasło nie przeszło pomyślnie weryfikacji.
Miałem niestandardowy walidator haseł, który nie był wywoływany podczas inicjowania bazy danych, więc reguły walidacji, do których byłem używany (minlength 4 zamiast domyślnego 6) nie miały zastosowania. Upewnij się, że Twoje hasło (i wszystkie inne pola w tym zakresie) przechodzi weryfikację.
źródło
IdentityResult result = manager.Create(user, "ChangeItAsap!"); if (result.Succeeded == false) { throw new Exception(result.Errors.First()); }
To jest moja metoda oparta na odpowiedzi Valina, dodałem role w db i dodałem hasło dla użytkownika. Ten kod jest umieszczony w
Seed()
metodzie w 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 == "[email protected]")) { var user = new ApplicationUser { UserName = "[email protected]", Email = "[email protected]", PasswordHash = PasswordHash.HashPassword("123456") }; UserManager.Create(user); UserManager.AddToRole(user.Id, Const.getRoles()[0]); }
źródło
Tutaj mam bardzo łatwe, czyste i gładkie rozwiązanie.
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); }
źródło
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 = "[email protected]", EmailConfirmed = true, PhoneNumber = "0123456789", PhoneNumberConfirmed = true }; await userManager.CreateAsync(user, "****"); await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName); } }
źródło
Task.Run(async () => { await SeedAsync(context); }).Wait();
. Powinieneś raczej napisać,SeedAsync(context).GetAwait().GetResult();
co jest nieznacznie lepsze.Wygląda na to, że zmieniły sposób, w jaki działa uwierzytelnianie w MVC5, zmieniły mój plik Global.asax.cs na następujący załatwił sprawę!
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(); } } }
źródło
napisz ten kod w swojej konfiguracji migracji.
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" } ); } }
źródło