visual update studio remove migrations migratedatabasetolatestversion force first existing enable code automaticmigrationsenabled automatic asp.net-mvc asp.net-mvc-5 ef-migrations seeding

asp.net mvc - update - MVC 5 Seed Users y Roles



remove migration (6)

Aquí hay un ejemplo del enfoque usual de Semillas:

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"); } }

Usé package-manager "update-database". DB y todas las tablas fueron creadas y sembradas con datos.

He estado jugando con el nuevo MVC 5, tengo algunos modelos, controlador y configuración de vistas usando código primeras migraciones.

Mi pregunta es ¿cómo puedo sembrar usuarios y roles? Actualmente siembro algunos datos de referencia en mi método Seed en Configuration.cs. Pero me parece que las tablas de usuario y roles no se crean hasta que algo golpea por primera vez al AccountController.

Actualmente tengo dos cadenas de conexión, por lo que puedo separar mis datos de mi autenticación en diferentes bases de datos.

¿Cómo puedo hacer que las tablas de usuario, roles, etc. se llenen junto con las demás? ¿Y no cuando se golpea el controlador de cuenta?


Aquí tengo una solución muy fácil, limpia y sin problemas.

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


Es una pequeña adición, pero para cualquiera que tenga el "UserId no encontrado". mensaje al intentar sembrar: (Tom Regan tuvo esta pregunta en los comentarios, y estuve atrapado en ella por un tiempo)

Esto significa que el administrador. Crear (usuario, "ChangeItAsap!") No fue exitoso. Esto podría tener una razón diferente, pero para mí fue porque mi contraseña no estaba teniendo éxito en su validación.

Tenía un validador de contraseñas personalizado, que no se llamaba al sembrar la base de datos, por lo que las reglas de validación a las que estaba acostumbrado (minlength 4 en lugar de default 6) no se aplicaron. Asegúrese de que su contraseña (y todos los otros campos para el caso) esté pasando la validación.


Este es mi método basado en la respuesta de Valin, he agregado funciones en db y he añadido una contraseña para el usuario. Este código se coloca en el método Seed() en 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]); }


Lo que hago es crear otro ethy asincrónico y llamarlo sincrónicamente, funciona perfecto para mí.

protected override void Seed(ApplicationDbContext context) { Task.Run(async () => { await SeedAsync(context); }).Wait(); } 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); } }


Parece que cambian la forma en que la autenticación funciona en MVC5, cambió mi Global.asax.cs por el siguiente: ¡el truco!

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