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

12

72

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?

Guitar answered 17/12, 2015 at 20:23 Comment(0)
A
93

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 = "[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;
    }

}

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);
Azar answered 19/12, 2015 at 8:3 Comment(10)
Yes! That's the way. Awesome code for helping people on seed data. ThanksGuitar
I was looking for a way to have a user with a fixed Id. The UserManager assigns a new Id when you hand over some ApplicationUser instance for creation. Your approach allows me to set the Id to some fixed value - so thanks for your effort :)Dongola
System.InvalidOperationException: 'ExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.'Kenney
There are few async issues in this code (i.e. userStore.CreateAsync is not guaranteed to finish before .AddToRolesAsync is called) but the concept is topHomespun
You, sir, are a hero.Nisan
Code is missing the async keyword on AssignRoles and context.SaveChangesAsync, and Initialize must return async Task. roleStore.CreateAsync also needs await.Tremblay
This gave me some error about using a scoped service for ApplicationDbContext or something...Cymograph
Getting error saying The non-generic method 'IServiceProvider.GetService(Type)' cannot be used with type argumentsChloroplast
@HamzaKhanzada the GetService methods are two, Use public static T GetService<T> from Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensionsUnsling
error with using a scoped service for ApplicationDbContext or somethingFowl
W
53

You can seed Users and Roles in OnModelCreating() method inside IdentityDbContext.cs file as shown below. Notice that the keys have to be predefined to avoid seeding new users and roles everytime this method is executed.

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Seeding a  'Administrator' role to AspNetRoles table
        modelBuilder.Entity<IdentityRole>().HasData(new IdentityRole {Id = "2c5e174e-3b0e-446f-86af-483d56fd7210", Name = "Administrator", NormalizedName = "ADMINISTRATOR".ToUpper() });


        //a hasher to hash the password before seeding the user to the db
        var hasher = new PasswordHasher<IdentityUser>();


        //Seeding the User to AspNetUsers table
        modelBuilder.Entity<IdentityUser>().HasData(
            new IdentityUser
            {
                Id = "8e445865-a24d-4543-a6c6-9443d048cdb9", // primary key
                UserName = "myuser",
                NormalizedUserName = "MYUSER",
                PasswordHash = hasher.HashPassword(null, "Pa$$w0rd")
            }
        );


        //Seeding the relation between our user and role to AspNetUserRoles table
        modelBuilder.Entity<IdentityUserRole<string>>().HasData(
            new IdentityUserRole<string>
            {
                RoleId = "2c5e174e-3b0e-446f-86af-483d56fd7210", 
                UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9"
            }
        );
        

    }
Working answered 13/8, 2020 at 7:59 Comment(13)
This is a working solution in .NET Core 3.1 (if you're okay with hardcoding some test data). I am using this approach myself.Coycoyle
This worked for me while the accepted one on top did not. ThanksVermont
This is the correct answer for .NET 5.0 as well.Ackler
This is not recommended by Micro$oftOtiose
@JonathanDaniel can you post a link to verify what you stated? i was looking into this and found this, which im assuming is showing the best approach if you meet certain factors. learn.microsoft.com/en-us/ef/core/modeling/data-seedingExobiology
@HeribertoLugo in the page you linked is written "Data that requires calls to external API, such as ASP.NET Core Identity roles and users creation''Otiose
@JonathanDaniel and? I was hoping you could provide documentation which states this is not recommended, because I could not find such and only found documentation which states it is valid.Exobiology
@JonathanDaniel you provided an authoritive statement without an authority to back it up. Personally I ended up using a different approach for ease of use, flexibility and better organization. But I still don't see any documentation stating this is bad practice or not recommended by Microsoft. Which is what I wanted to read.Exobiology
@HeribertoLugo I am quoting literally what microsoft wrote: "If your scenario includes any of the following it is recommended to use custom initialization logic described in the last section: ... Data that requires calls to external API, such as ASP.NET Core Identity roles and users creation"Otiose
you're right.. not sure how i overlooked that last bullet point about 5 times of reading it. thanks for pointing it out twice.Exobiology
I think the problem with this answer is that it updates Concurrency Stamp whenever new migration is added. It's not recommended but it does the trick.Joceline
@LukaszPomianowski is right: i was using this and i'm switching to seed version because ASPNet.core detects again and again changes in the database context and complains about pending changes... furthermore, each time you use the migrate command without real changes, it detects changes on the Concurrency stamp and generates a new migration.Ramillies
unfortunately the missing concurrency stamp columns will create all kinds of problems with this approach.Meaningful
D
35

As of the time of this writing, there is no plug in place for seeding the database, but you can create a class and add it to your container to do the same thing on app start, here is how I've done it, first create a class:

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

Register the type in ConfigureServices method of your Startup.cs class:

services.AddTransient<YourDbContextSeedData>();

Next pass the YourDbContextSeedData class to the Configure method of your Startup.cs class and use it:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, YourDbContextSeedData seeder)
{
  seeder.SeedAdminUser();
}
Dissert answered 14/1, 2016 at 14:20 Comment(4)
After many wasted hours trying to seed an admin level account in my core 2 app a slightly modified version of your post finally did it for me while all other approaches failed when i called the AddToRoleAsync method. Thank you so much!Emotionalize
This was helpful, thanks @Hamid. I would suggest to others that you actually call the initializer from Program.Main() - see this answer for an explanation. My app would not load consistently until I moved the initialization out of startup. And per this post, you may want to consider using UserManager and RoleManager for validation.Cynical
Note that the call: await userStore.AddToRoleAsync(user, "admin"); the "admin" is the normalized value of the Role so if yours differ be sure to make sure it reflects the value specified in the normalized role.Aylmer
Got this to work in EF6. My gotcha was the normalized username and email had to be UPPERCASE!Terry
B
5

If you have async issues, try the following code:

    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();
    }
Byerly answered 17/5, 2018 at 14:33 Comment(0)
B
4

In aspnetcore there is the concept of IHostedService. This makes it possible to run async background Task.

The solution of @hamid-mosalla could be made async and called from an IHostedService implementation.

Seed class implementation could be something like

public class IdentityDataSeeder
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;

    public IdentityDataSeeder(
        UserManager<ApplicationUser> userManager,
        RoleManager<IdentityRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }

    public async Task SeedAsync()
    {
        var superAdminRole = new IdentityRole
        {
            Id = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
            Name = "SuperAdmin",
            NormalizedName = "SUPERADMIN"
        };
        await CreateRoleAsync(superAdminRole);

        var superAdminUserPassword = "P@ssword1";
        var superAdminUser = new ApplicationUser
        {
            Id = "b8633e2d-a33b-45e6-8329-1958b3252bbd",
            UserName = "[email protected]",
            NormalizedUserName = "[email protected]",
            Email = "[email protected]",
            NormalizedEmail = "[email protected]",
            EmailConfirmed = true,
        };
        await CreateUserAsync(superAdminUser, superAdminUserPassword);

        var superAdminInRole = await _userManager.IsInRoleAsync(superAdminUser, superAdminRole.Name);
        if (!superAdminInRole)
            await _userManager.AddToRoleAsync(superAdminUser, superAdminRole.Name);
    }

    private async Task CreateRoleAsync(IdentityRole role)
    {
        var exits = await _roleManager.RoleExistsAsync(role.Name);
        if (!exits)
            await _roleManager.CreateAsync(role);
    }

    private async Task CreateUserAsync(ApplicationUser user, string password)
    {
        var exists = await _userManager.FindByEmailAsync(user.Email);
        if (exists == null)
            await _userManager.CreateAsync(user, password);
    }
}

This can be called from an IHostedService:

public class SetupIdentityDataSeeder : IHostedService
{
    private readonly IServiceProvider _serviceProvider;
    public SetupIdentityDataSeeder(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            var seeder = scope.ServiceProvider.GetRequiredService<IdentityDataSeeder>();

            await seeder.SeedAsync();
        }
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

Startup would look like:

public void ConfigureServices(IServiceCollection services)
{
    //...

    services.AddHostedService<SetupIdentityDataSeeder>();
}
Boser answered 27/10, 2020 at 20:26 Comment(4)
From my understanding, an IHostedService continually runs in the background until the application process is stopped. If that is the case, then it is not the appropriate place to do a one-time task like seeding the database.Gooden
@Gooden the documentation states: The hosted service is activated once at app startup and gracefully shut down at app shutdown. See MS docs.Boser
Yes, that is exactly my point. A hosted service is used for something that needs to run repeatedly the entire time your application is running. If you want to seed the database with something (a task that only needs to happen once), you can do it just once during app start (with async support) up as shown here: https://mcmap.net/q/275855/-how-do-i-seed-user-roles-in-identity-asp-net-core-2-1-identity-scaffoldedGooden
@Gooden It is not true that it needs to run repeatedly the entire time. IHostedService is used for background tasks and scheduled jobs. Here it is used to run the code as a background task. To run it repeatedly you need to make use of the Timer. Since that is not done here this will run once at application start. I just want to offload a task to the background and I am using a build in mechanism for that.Boser
Q
4

My way:

  1. Create Class in models folder

    public static class ModelBuilderExtensions
      {
    
         public static void Seed(this ModelBuilder builder)
         {
    
        // Seed Roles
    
        List<IdentityRole> roles = new List<IdentityRole>()
        {
            new IdentityRole { Name = "Admin", NormalizedName = "ADMIN" },
            new IdentityRole { Name = "User", NormalizedName = "USER" }
        };
    
        builder.Entity<IdentityRole>().HasData(roles);
    
        // -----------------------------------------------------------------------------
    
        // Seed Users
    
        var passwordHasher = new PasswordHasher<ApplicationUser>();
    
        List<ApplicationUser> users = new List<ApplicationUser>()
        {
             // imporant: don't forget NormalizedUserName, NormalizedEmail 
                     new ApplicationUser {
                        UserName = "[email protected]",
                        NormalizedUserName = "[email protected]",
                        Email = "[email protected]",
                        NormalizedEmail = "[email protected]",
                    },
    
                    new ApplicationUser {
                        UserName = "[email protected]",
                        NormalizedUserName = "[email protected]",
                        Email = "[email protected]",
                        NormalizedEmail = "[email protected]",
                    },
        };
    
    
        builder.Entity<ApplicationUser>().HasData(users);
    
        ///----------------------------------------------------
    
        // Seed UserRoles
    
    
        List<IdentityUserRole<string>> userRoles = new List<IdentityUserRole<string>>();
    
          // Add Password For All Users
    
            users[0].PasswordHash = passwordHasher.HashPassword(users[0], "User.123");
            users[1].PasswordHash = passwordHasher.HashPassword(users[1], "User.155");
    
             userRoles.Add(new IdentityUserRole<string> { UserId = users[0].Id, RoleId = 
             roles.First(q => q.Name == "User").Id });
    
             userRoles.Add(new IdentityUserRole<string> { UserId = users[1].Id, RoleId = 
             roles.First(q => q.Name == "Admin").Id });
    
    
        builder.Entity<IdentityUserRole<string>>().HasData(userRoles);
    
    }}
    
  2. in DBContext

    public class AppDbContext : IdentityDbContext<ApplicationUser>
     {
    
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }
    
    protected override void OnModelCreating(ModelBuilder builder)
    {
        // Use seed method here
        builder.Seed();
        base.OnModelCreating(builder);
    }}
    
Quarter answered 20/3, 2021 at 11:12 Comment(2)
This solution will re-create roles as the ID is not provided. Then it will update Concurrency stamp unless that will be provided too. Almost the same as @hamza's answerJoceline
Not exactly. HasData works with your schema's data. A migration must be created for it to make any inserts, updates, or deletes. See #71744608 for clarity.Tarboosh
F
3

This is not yet implemented. As a work around, just write your own class that will check the database for the existence of your entities, add them if they don't exist, and call this class from your Startup.cs.

Flynt answered 18/12, 2015 at 0:7 Comment(2)
As per Microsoft, The seeding code should not be part of the normal app execution as this can cause concurrency issues when multiple instances are running and would also require the app having permission to modify the database schema. learn.microsoft.com/en-us/ef/core/modeling/…Chloroplast
@HamzaKhanzada I first check if env is development and then seed, and then I create a seperate program that will seed it for production that should be ran manually once.Otiose
U
2

Add the following class in Models namespace. It works for adding multiple users and roles, and will also add roles to existing users (e.g. facbook logins). Call it like this app.SeedUsersAndRoles(); from 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);
        }
    }
}
Unsnap answered 23/3, 2016 at 11:11 Comment(0)
L
2

By Using Extension Method.

namespace Course.Repository.Utilities {
    public  static class AddRoleToAdmin {
       public static void ConfigurationUserAndRole(this ModelBuilder modelBuilder)
        {
            //Seeding a  'Administrator' role to AspNetRoles table
            modelBuilder.Entity<IdentityRole>().HasData(
                new IdentityRole()
                {
                    Id = "2c5e174e-3b0e-446f-86af-483d56fd7210",
                    Name = "Admin",
                    NormalizedName = "Admin".ToUpper()
                }
                );
            var hasher = new PasswordHasher<IdentityUser>();
            // Seeding the User to AspNetUsers table
            modelBuilder.Entity<AppUser>().HasData(
               new AppUser()
               {
                   Id= "8e445865-a24d-4543-a6c6-9443d048cdb9",
                   UserName = "[email protected]",
                   Email = "[email protected]",
                   NormalizedUserName = "[email protected]".ToUpper(),
                   NormalizedEmail = "[email protected]".ToUpper(),
                   PasswordHash = hasher.HashPassword(null, "Admin123"),
                   EmailConfirmed = true,
                   LockoutEnabled = true,
                   PhoneNumberConfirmed = true,
                   SecurityStamp = Guid.NewGuid().ToString()
               }
                );
            //Seeding the relation between our user and role to AspNetUserRoles table

            modelBuilder.Entity<IdentityUserRole<string>>().HasData(
                new IdentityUserRole<string>()
                {
                    RoleId= "2c5e174e-3b0e-446f-86af-483d56fd7210", // 2c5e174e-3b0e-446f-86af-483d56fd7210
                    UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9" // 8e445865-a24d-4543-a6c6-9443d048cdb9
                }
                );
        }
    }
}

OnModelCreating In DbContext

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            
            base.OnModelCreating(modelBuilder);
             // Call Extension Method.
            modelBuilder.ConfigurationUserAndRole(); 
        }
Lues answered 24/3, 2023 at 14:34 Comment(0)
H
1

So this is solution based on Muhammad Abdullah answer. Included few code improvements, improved readability of code and got it to work with .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);
            }           
        }
    }
Homespun answered 10/3, 2018 at 20:30 Comment(0)
S
1

Seems this thread is very old, but it will still work for someone who wants to seed their identity tables data in entityframework core.

You can simple try the below.

modelBuilder.Entity<IdentityUser>().HasData(
               new IdentityUser { Id= "-1", UserName="sagark",PasswordHash="sagark", Email="emailid goes here" }
               );
Sequence answered 15/4, 2020 at 13:35 Comment(1)
This approach is NOT recommended. How will you login without a properly hashed password? Additionally, without a preset ID you will never be able to add the user to any roles or establish any relationships when seeding.Coycoyle
T
0

The following line create the entry in the AspNetRoles table but does not populate the NormalizedName column.

Substitute with the following for this column to be populated:

RoleManager<IdentityRole> roleManager = serviceProvider.GetService<RoleManager<IdentityRole>>();
roleManager.CreateAsync(new IdentityRole(role));
Thermography answered 8/1, 2016 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.