varios update tutorial tipos reconoce nombre net mvc migrations migraciones migracion han habilitar framework first español ensamblado encontrado enable crear contexto como code asp ef-code-first asp.net-identity asp.net-core-mvc seeding

ef code first - update - Cómo generar usuarios y roles con la migración de Code First mediante Identity ASP.NET MVC 6



se han encontrado varios tipos de contexto en el ensamblado (7)

Agregue la siguiente clase en el espacio de nombres de los modelos. Funciona para agregar múltiples usuarios y roles, y también agregará roles a usuarios existentes (por ejemplo, inicios de sesión de facbook). Llámelo como esta app.SeedUsersAndRoles(); desde startup.cs

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity; namespace MyApplication.Models { public static class DataSeeder { public static async void SeedUsersAndRoles(this IApplicationBuilder app) { var context = app.ApplicationServices.GetService<ApplicationDbContext>(); UserWithRoles[] usersWithRoles = { new UserWithRoles("Admin", new string[] { "Administrator" , "Distributor" },"somepassword"),//user and optional roles and password you want to seed new UserWithRoles("PlainUser"), new UserWithRoles("Jojo",new string[]{"Distributor" }) //seed roles to existing users (e.g. facebook login). }; foreach (var userWithRoles in usersWithRoles) { foreach (string role in userWithRoles.Roles) if (!context.Roles.Any(r => r.Name == role)) { var roleStore = new RoleStore<IdentityRole>(context); await roleStore.CreateAsync(new IdentityRole(role)); } var ExistingUser = context.Users.FirstOrDefault(p => p.NormalizedUserName == userWithRoles.User.NormalizedUserName); if (ExistingUser == null) //the following syntax: !context.Users.FirstOrDefault(p => p.NormalizedUserName == userWithRoles.User.NormalizedUserName)) //provokes execption:(ExecuteReader requires an open and available Connection.) await new UserStore<ApplicationUser>(context).CreateAsync(userWithRoles.User); await app.AssignRoles(userWithRoles); //assign also to existing users. } context.SaveChangesAsync(); } public static async Task<IdentityResult> AssignRoles(this IApplicationBuilder app, UserWithRoles uWR) { UserManager<ApplicationUser> _userManager = app.ApplicationServices.GetService<UserManager<ApplicationUser>>(); ApplicationUser user = await _userManager.FindByNameAsync(uWR.User.NormalizedUserName); var result = await _userManager.AddToRolesAsync(user, uWR.Roles); return result; } } public class UserWithRoles { private ApplicationUser user; public ApplicationUser User { get { return user; } } public string[] Roles { get; set; } public UserWithRoles(string name, string[] roles = null, string password = "secret") { if (roles != null) Roles = roles; else Roles = new string[] { }; user = new ApplicationUser { Email = name + "@gmail.com", NormalizedEmail = name.ToUpper() + "@GMAIL.COM", UserName = name, NormalizedUserName = name.ToUpper(), PhoneNumber = "+1312341234", EmailConfirmed = true, PhoneNumberConfirmed = true, SecurityStamp = Guid.NewGuid().ToString("D"), }; user.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(user, password); } } }

He creado un nuevo proyecto limpio de asp.net 5 (rc1-final). Usando la autenticación de identidad, acabo de tener ApplicationDbContext.cs con el siguiente código:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { protected override void OnModelCreating(ModelBuilder builder) { // On event model creating base.OnModelCreating(builder); } }

Tenga en cuenta que ApplicationDbContext utiliza IdentityDbContext y no DbContext.

Hay cualquier IdentityConfig.cs. ¿Dónde necesito colocar la invalidación protegida anulada clásica para crear un rol y un usuario si no existe?


Así que esta es una solución basada en la respuesta de Muhammad Abdullah. Incluyó algunas mejoras de código, mejor legibilidad del código y consiguió que funcionara con .net core 2.

public class Seed { public static async Task Initialize(IServiceProvider serviceProvider, IConfiguration configuration) { var usrName = configuration.GetSection("Admin").GetSection("UserName").Value; var email = configuration.GetSection("Admin").GetSection("Email").Value; var pass = configuration.GetSection("Admin").GetSection("Pass").Value; var roles = new string[4] { OWNER, ADMIN, SENIOR, USER }; if(await CreateUser(serviceProvider, email, usrName, pass, roles)) { await AddToRoles(serviceProvider, email, roles); } } private static async Task<bool> CreateUser(IServiceProvider serviceProvider, string email, string usrName, string pass, string[] roles) { var res = false; using (var scope = serviceProvider.CreateScope()) { var context = scope.ServiceProvider.GetService<BaseContext>(); if (!context.ApplicationUsers.Any(u => u.NormalizedUserName == usrName.ToUpper())) { var roleStore = scope.ServiceProvider.GetService<RoleManager<IdentityRole>>(); foreach (string role in roles) { if (!context.Roles.Any(r => r.Name == role)) { await roleStore.CreateAsync(new IdentityRole(role)).ConfigureAwait(false); } } var user = new ApplicationUser { UserName = usrName, Email = email, EmailConfirmed = true, NormalizedEmail = email.ToUpper(), NormalizedUserName = usrName.ToUpper(), PhoneNumber = null, PhoneNumberConfirmed = true, SecurityStamp = Guid.NewGuid().ToString() }; var password = new PasswordHasher<ApplicationUser>(); user.PasswordHash = password.HashPassword(user, pass); ; var userStore = new UserStore<ApplicationUser>(context); res = (await userStore.CreateAsync(user).ConfigureAwait(false)).Succeeded; } return res; } } private static async Task AddToRoles(IServiceProvider serviceProvider, string email, string[] roles) { using (var scope = serviceProvider.CreateScope()) { var userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>(); var usr = await userManager.FindByEmailAsync(email).ConfigureAwait(false); await userManager.AddToRolesAsync(usr, roles).ConfigureAwait(false); } } }


En el momento de escribir este artículo, no hay ningún complemento para sembrar la base de datos, pero puede crear una clase y agregarla a su contenedor para hacer lo mismo en el inicio de la aplicación. A continuación le indicamos cómo lo he hecho, primero crear una clase:

public class YourDbContextSeedData { private YourDbContext _context; public YourDbContextSeedData(YourDbContext context) { _context = context; } public async void SeedAdminUser() { var user = new ApplicationUser { UserName = "[email protected]", NormalizedUserName = "[email protected]", Email = "[email protected]", NormalizedEmail = "[email protected]", EmailConfirmed = true, LockoutEnabled = false, SecurityStamp = Guid.NewGuid().ToString() }; var roleStore = new RoleStore<IdentityRole>(_context); if (!_context.Roles.Any(r => r.Name == "admin")) { await roleStore.CreateAsync(new IdentityRole { Name = "admin", NormalizedName = "admin" }); } if (!_context.Users.Any(u => u.UserName == user.UserName)) { var password = new PasswordHasher<ApplicationUser>(); var hashed = password.HashPassword(user, "password"); user.PasswordHash = hashed; var userStore = new UserStore<ApplicationUser>(_context); await userStore.CreateAsync(user); await userStore.AddToRoleAsync(user, "admin"); } await _context.SaveChangesAsync(); }

Registre el tipo en el método ConfigureServices de su clase Startup.cs :

services.AddTransient<YourDbContextSeedData>();

Luego pase la clase YourDbContextSeedData al método Configure de su clase Startup.cs y YourDbContextSeedData :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, YourDbContextSeedData seeder) { seeder.SeedAdminUser(); }


Esto aún no está implementado . Como solución, simplemente escriba su propia clase que verificará la base de datos para ver la existencia de sus entidades, agréguelas si no existen y llame a esta clase desde su Startup.cs.


La siguiente línea crea la entrada en la tabla AspNetRoles pero no llena la columna NormalizedName.

Sustituya con lo siguiente para que se complete esta columna:

RoleManager<IdentityRole> roleManager = serviceProvider.GetService<RoleManager<IdentityRole>>(); roleManager.CreateAsync(new IdentityRole(role));


Mi forma de hacerlo es crear una clase en el espacio de nombres de los modelos.

public class SampleData { public static void Initialize(IServiceProvider serviceProvider) { var context = serviceProvider.GetService<ApplicationDbContext>(); string[] roles = new string[] { "Owner", "Administrator", "Manager", "Editor", "Buyer", "Business", "Seller", "Subscriber" }; foreach (string role in roles) { var roleStore = new RoleStore<IdentityRole>(context); if (!context.Roles.Any(r => r.Name == role)) { roleStore.CreateAsync(new IdentityRole(role)); } } var user = new ApplicationUser { FirstName = "XXXX", LastName = "XXXX", Email = "[email protected]", NormalizedEmail = "[email protected]", UserName = "Owner", NormalizedUserName = "OWNER", PhoneNumber = "+111111111111", EmailConfirmed = true, PhoneNumberConfirmed = true, SecurityStamp = Guid.NewGuid().ToString("D") }; if (!context.Users.Any(u => u.UserName == user.UserName)) { var password = new PasswordHasher<ApplicationUser>(); var hashed = password.HashPassword(user,"secret"); user.PasswordHash = hashed; var userStore = new UserStore<ApplicationUser>(context); var result = userStore.CreateAsync(user); } AssignRoles(serviceProvider, user.Email, roles); context.SaveChangesAsync(); } public static async Task<IdentityResult> AssignRoles(IServiceProvider services, string email, string[] roles) { UserManager<ApplicationUser> _userManager = services.GetService<UserManager<ApplicationUser>>(); ApplicationUser user = await _userManager.FindByEmailAsync(email); var result = await _userManager.AddToRolesAsync(user, roles); return result; } }

Para ejecutar este código en el inicio. En Startup.cs al final del método de configuración, justo después de la configuración de la ruta, agregue el siguiente código como lo dijo antes Stafford Williams.

SampleData.Initialize(app.ApplicationServices);


Si tienes problemas asíncronos, prueba el siguiente código:

protected override void Seed(ApplicationDbContext context) { // This method will be called after migrating to the latest version. string[] roles = new string[] { "Admin", "User" }; foreach (string role in roles) { if (!context.Roles.Any(r => r.Name == role)) { context.Roles.Add(new IdentityRole(role)); } } //create user UserName:Owner Role:Admin if (!context.Users.Any(u => u.UserName == "Owner")) { var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); var user = new ApplicationUser { FirstName = "XXXX", LastName = "XXXX", Email = "[email protected]", UserName = "Owner", PhoneNumber = "+111111111111", EmailConfirmed = true, PhoneNumberConfirmed = true, SecurityStamp = Guid.NewGuid().ToString("D"), PasswordHash = userManager.PasswordHasher.HashPassword("secret"), LockoutEnabled = true, }; userManager.Create(user); userManager.AddToRole(user.Id, "Admin"); } context.SaveChanges(); }