ef-code-firstasp.net-identityasp.net-core-mvcseeding

How to Seed Users and Roles with Code First Migration using Identity ASP.NET Core


I have created a new clean asp.net 5 project (rc1-final). Using Identity Authentication I just have the ApplicationDbContext.cs with the following code:

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

Please note ApplicationDbContext use IdentityDbContext and not DbContext.

There is any IdentityConfig.cs. Where i need to put the classic protected override void Seed to create role and user if it does not exist?


Solution

  • My way of doing this is to create a class in models namespace.

    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 = "xxxx@example.com",
                NormalizedEmail = "XXXX@EXAMPLE.COM",
                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;
        }
    
    }
    

    To run this code on startup. In Startup.cs at end of configure method just after route configuration add following code as Stafford Williams said before.

    SampleData.Initialize(app.ApplicationServices);