Entity Framework 7 > Seed a user and setting up roles

During my coding travels the other day, I was combing the web in search for a tutorial on how to add an initial user (via migrations) and setup a role for that user in EF7.  Being unable to find such a post, I have decided to post my own as a tutorial.

SETTING UP AN ‘ADMIN’ USER AND ‘ADMIN’ ROLE

I would have imagined that to set this up, the code should go somewhere in the ‘Migrations’ code files.  Ironically enough, this didn’t seem to work for me.  Hopefully in the future this sort of thing will go in ‘Migrations’, but at this point in time, I turned elsewhere to ‘Models/ApplicationDbContext.cs’ and ‘Startup.cs’.  When ‘Startup.cs’ is executed upon project startup, it can check for seed users/roles.  And DB accessibility is available via ‘ApplicationDbContext.cs’

As for the code that does this magic, it is as follows:

Startup.cs


...
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseApplicationInsightsRequestTelemetry();

            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();

                try
                {
                    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                        .CreateScope())
                    {
                        serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                             .Database.Migrate();

                        var userManager = app.ApplicationServices.GetService<UserManager<ApplicationUser>>();
                        var roleManager = app.ApplicationServices.GetService<RoleManager<IdentityRole>>();

                        serviceScope.ServiceProvider.GetService<ApplicationDbContext>().EnsureSeedData(userManager, roleManager);
                    }
                }
                catch { }
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");

                // For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
                try
                {
                    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                        .CreateScope())
                    {
                        serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                             .Database.Migrate();

                        var userManager = app.ApplicationServices.GetService<UserManager<ApplicationUser>>();
                        var roleManager = app.ApplicationServices.GetService<RoleManager<IdentityRole>>();

                        serviceScope.ServiceProvider.GetService<ApplicationDbContext>().EnsureSeedData(userManager, roleManager);
                    }
                }
                catch { }
            }
...

 

ApplicationDbContext.cs


public class ApplicationDbContext : IdentityDbContext
    {
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            // Customize the ASP.NET Identity model and override the defaults if needed.
            // For example, you can rename the ASP.NET Identity table names and more.
            // Add your customizations after calling base.OnModelCreating(builder);

        }

        public async void EnsureSeedData(UserManager userMgr,RoleManager roleMgr)
        {
            if (!this.Users.Any(u => u.UserName == "admin@mydomain.com"))
            {
                // Add 'admin' role
                var adminRole = await roleMgr.FindByNameAsync("admin");
                if (adminRole == null)
                {
                    adminRole = new IdentityRole("admin");
                    await roleMgr.CreateAsync(adminRole);
                }

                // create admin user
                var adminUser = new ApplicationUser();
                adminUser.UserName = "admin@mydomain.com";
                adminUser.Email = "admin@mydomain.com";

                await userMgr.CreateAsync(adminUser, "MYP@55word");

                await userMgr.SetLockoutEnabledAsync(adminUser, false);
                await userMgr.AddToRoleAsync(adminUser, "admin");
            }
        }
...

NOTES

  • If you find your seed user is not being added, it could be due to your password not meeting password restriction requirements.  To check, change the line to
    var result = await userMgr.CreateAsync(adminUser, "<YOURPASSWORDHERE>");

    and view the result variable in the debugger to see what requirements you are missing

  • In Startup.cs, you need to place repeating code in both the
    if (env.IsDevelopment())

    and the else block that follows.  This is so that the ‘EnsureSeedData’ function is called regardless to whether the environment is currently in dev mode, or prod mode.

 

Hope this helps, and happy coding! 🙂

 

8 thoughts on “Entity Framework 7 > Seed a user and setting up roles”

    1. Hi thorne,

      UserManager is located in the .NET libraries under Microsoft.AspNet.Identity.UserManager.

      Cheers,

      Jeff

  1. I’m adding additional data after yours, however I’m getting a connection is closed error with EF7.

    Any ideas?

    await userMgr.CreateAsync(adminUser, “MYP@55word”);

    await userMgr.SetLockoutEnabledAsync(adminUser, false);
    await userMgr.AddToRoleAsync(adminUser, “user”);
    }

    // default band
    if (!this.band.Any(u => u.name == “Jazz01”))
    {

    1. No sorry, I’m not really sure what to do here. Maybe its because you are creating the same user twice in the DB? Otherwise, it could be database issue in general, meaning your DB credentials are invalid or the DB itself is not available.

Leave a Reply

Your email address will not be published. Required fields are marked *