3
votes

What I'm trying to do is to add a new admin user and assign it with the admin role. So.. I went to the Startup.cs class in Configure method and wrote the following code:

var context = app.ApplicationServices.GetService<ApplicationDbContext>();

// Getting required parameters in order to get the user manager
var userStore = new UserStore<ApplicationUser>(context);

// Finally! get the user manager!
var userManager = new UserManager<ApplicationUser>(userStore);

However, I get the following error message:

Severity Code Description Project File Line Suppression State Error CS7036 There is no argument given that corresponds to the required formal parameter 'optionsAccessor' of UserManager.UserManager(IUserStore, IOptions, IPasswordHasher, IEnumerable>, IEnumerable>, ILookupNormalizer, IdentityErrorDescriber, IServiceProvider, ILogger>)' FinalProject..NETCoreApp,Version=v1.0 C:\Users\Or Natan\Documents\Visual Studio 2015\Projects\FinalProject\src\FinalProject\Startup.cs 101 Active

This error is killing me here.. obviously I need the userManager in order to create the new user but I just can't initialize this thing.

2
to seed data from startup typically people do that directly with DBContext, or maybe you could do it with UserStore. google about seeding data with EF Core, see music store app etc. you might be interested in my project which provides a ui for managing identity users and roles and claims and auto creates an admin user for the site during startup github.com/joeaudette/cloudscribe - Joe Audette

2 Answers

5
votes

You can use dependency injection to obtain an instance of UserManager. Just add a parameter to the configure method, like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext context, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)

Then you can create users and roles. I usually move this code into a static class...

public static class DbInitializer
{
    public static async Task Initialize(ApplicationDbContext context, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
    {
        // Ensure that the database exists and all pending migrations are applied.
        context.Database.Migrate();

        // Create roles
        string[] roles = new string[] { "UserManager", "StaffManager" };
        foreach (string role in roles)
        {
            if (!await roleManager.RoleExistsAsync(role))
            {
                await roleManager.CreateAsync(new IdentityRole(role));
            }
        }

        // Create admin user
        if (!context.Users.Any())
        {
            await userManager.CreateAsync(new ApplicationUser() { UserName = "[email protected]", Email = "[email protected]" }, "p@ssw0rd");
        }

        // Ensure admin privileges
        ApplicationUser admin = await userManager.FindByEmailAsync("[email protected]");
        foreach (string role in roles)
        {
            await userManager.AddToRoleAsync(admin, role);
        }
    }
}

... and call the method in the Startup.Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext context, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
{
    // Code omitted for brevity

    // Create seed data
    DbInitializer.Initialize(context, userManager, roleManager).Wait();
}

In one of the next releases of Entity Framework Core database seeding will be added as a feature.

1
votes

As @JuliusHardt said you can get instance of UserManager via dependency injection. for seeding database first create Extension method like this:

public static class ApplicationDbContextExtensions
{
    public static void EnsureSeedData(this ApplicationDbContext context, UserManager<ApplicationUser> userManager)
    {
        if (!context.Users.Any())
        {
            var result = userManager.CreateAsync(
                new ApplicationUser { UserName = "[email protected]", Email = "[email protected]" },
                "P@ssw0rd").Result;
        }
    }
}

and in Startup class and in Configure method:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
    app.UseBrowserLink();
    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
    {
        // First apply pendding migrations if exist
        serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate();

        // Then call seeder method
        var userManager = serviceScope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
        serviceScope.ServiceProvider.GetService<ApplicationDbContext>().EnsureSeedData(userManager);
    }
}