1

I am using Identity 3. I want to seed an admin user on startup.

I have converted the string ids to "int" ids using as an example SwiftCourier on github. Identity 3 is different in some aspects and this applies to the setting of "int" for ids as shown in the SwiftCourier example as compared to Identity 2 and the setting of "int" ids.

I've done this by placing "int" after my user:

public class User : IdentityUser<int>{...}

After my Role:

public class Role : IdentityRole<int>

and in startup.cs in configuration services I entered this:

            services.AddIdentity<User, Role>(options => options.User.AllowedUserNameCharacters = null)
            .AddEntityFrameworkStores<JobsDbContext, int>()
            .AddUserStore<UserStore<User, Role, JobsDbContext, int>>()
            .AddRoleStore<RoleStore<Role, JobsDbContext, int>>()
            .AddDefaultTokenProviders();

I then used this to seed roles and it works with integer ids:

public static void EnsureRolesCreated(this IApplicationBuilder app)
    {
        var context = app.ApplicationServices.GetService<JobsDbContext>();
        if (context.AllMigrationsApplied())
        {
            var roleManager = app.ApplicationServices.GetService<RoleManager<Role>>();

            var Roles = new List<Role>();

            Roles.Add(new Role { Name = "Admin", Description = "Users able to access all areas" });
            Roles.Add(new Role { Name = "Technician", Description = "Users able to access just the schedule" });

            foreach (var role in Roles)
            {
                if (!roleManager.RoleExistsAsync(role.Name.ToUpper()).Result)
                {
                    roleManager.CreateAsync(role);
                }
            }
        }
    }

So far so good... I want to seed just one admin user to start with and this is where I fail...

I have used the following Stackoverflow example by @Guy.

I am struggling with UserStore with this line:

await new UserStore<User>(context).CreateAsync(userWithRoles.User);

It fails on "User" which is my ApplicationUser just renamed.

The error I get is:

The type 'JobsLedger.Models.Identity.User' cannot be used as type parameter 'TUser' in the generic type or method 'UserStore<TUser>'. There is no implicit reference conversion from 'JobsLedger.Models.Identity.User' to 'Microsoft.AspNet.Identity.EntityFramework.IdentityUser<string>'.

It seems to be complaining on the fact that the id is "int" I think

How do I make the UserStore work with an "int"in this regard?? Its set to int in the Startup.cs as shown above..

If I have to create a custom "UserStore" that works with "int".. how do you do it in Identity 3?

Community
  • 1
  • 1
si2030
  • 3,895
  • 8
  • 38
  • 87
  • I gave an example of adding the user to roles, did it help? If it did then pls mark the answer as right answer – jamiedanq Apr 24 '16 at 06:37
  • I have just done that. I cant get the user to be created here using int ids let alone add roles to the user.. its failing on userstore.. – si2030 Apr 24 '16 at 06:51

1 Answers1

2

It might not be the most elegant solution but this works...

My aim was to seed an admin user and also to be added to the admin role. I have managed this while avoiding using UserStoreand with integer IDs.

using JobsLedger.DAL;
using JobsLedger.Models.Identity;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace JobsLedger.Models.Seeding
{
    public static class SeedAdminUser
    {
        public static async void EnsureAdminUserCreated(this IApplicationBuilder app)
        {
            var context = app.ApplicationServices.GetService<JobsDbContext>();
            if (context.AllMigrationsApplied())
            {
                var userManager = app.ApplicationServices.GetService<UserManager<User>>();
                var roleManager = app.ApplicationServices.GetService<RoleManager<Role>>();

                var user = new User
                {
                    UserName = "Admin",
                    NormalizedUserName = "ADMIN",
                    Email = "Email@email.com",
                    NormalizedEmail = "email@email.com",
                    EmailConfirmed = true,
                    LockoutEnabled = false,
                    SecurityStamp = Guid.NewGuid().ToString()
                };

                var password = new PasswordHasher<User>();
                var hashed = password.HashPassword(user, "password");
                user.PasswordHash = hashed;

                var result = await userManager.CreateAsync(user, user.PasswordHash);

                var AdminUser = await userManager.FindByNameAsync("Admin");

                if (AdminUser != null)
                {
                    if (roleManager.RoleExistsAsync("Admin").Result)
                    {
                        var RoleResult = await userManager.AddToRoleAsync(AdminUser, "Admin");
                    }
                }
            }
        }
    }
}

I also placed this entry into the StartUp.cs class after "app.UseIdentity();":

app.EnsureAdminUserCreated();

...Models.Identity has the "User" class in it and thats why its included in "using".

You will also need to add the following to make this work:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.DependencyInjection;
using System;

Finally you will need roles to already be added as per the question above..

si2030
  • 3,895
  • 8
  • 38
  • 87