DotNet Core 2种子用户和角色

时间:2018-03-01 20:50:30

标签: .net-core asp.net-core-mvc asp.net-core-2.0

使用VS2017内置的模板进行Core 2 MVC和身份验证。尝试使用用户和角色为数据库设定种子。角色运作良好,他们种子。用户总是返回一个错误,说“不能为空”,我认为是因为初始化函数末尾的这一行实际上找不到用户

await _userManager.AddToRoleAsync(await _userManager.FindByNameAsync(user), "Administrator");

我用这篇文章来构建它: https://gist.github.com/mombrea/9a49716841254ab1d2dabd49144ec092

注意 - 这篇文章是针对Core 1.0的,我使用的是Core 2.0,这可能就是我遇到问题的原因。

如前所述,我可以播种角色,但用户并没有创建自己。一旦我想到这一点,我将尝试多个用户,我已经做了一个测试创建多个角色。

这是初始化类

//Taken from :
    //https://gist.github.com/mombrea/9a49716841254ab1d2dabd49144ec092
    public interface IdentityDBIitializer
    {
        void Initialize();
    }

    public class LatestUserDBInitializer : IdentityDBIitializer
    {
        private readonly ApplicationDbContext _context;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<IdentityRole> _roleManager;

        public LatestUserDBInitializer(
            ApplicationDbContext context,
            UserManager<ApplicationUser> userManager,
            RoleManager<IdentityRole> roleManager)
        {
            _context = context;
            _userManager = userManager;
            _roleManager = roleManager;
        }

        //This example just creates an Administrator role and one Admin users
        public async void Initialize()
        {
            //create database schema if none exists
            _context.Database.EnsureCreated();

            //If there is already an Administrator role, abort
            //if (_context.Roles.Any(r => r.Name == "Administrator")) return;

            //Create the Administartor Role
            //await _roleManager.CreateAsync(new IdentityRole("Administrator"));

            //Create the default Admin account and apply the Administrator role
            string user = "me@myemail.com";
            string password = "z0mgchangethis";
            await _userManager.CreateAsync(new ApplicationUser { UserName = user, Email = user, EmailConfirmed = true }, password);
            await _userManager.AddToRoleAsync(await _userManager.FindByNameAsync(user), "Administrator");
        }
    }

这是我的STartup:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<POSContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("UKFest2018Context")));

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("UKFestIdentityContext")));

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();


            // Add Database Initializer
            services.AddScoped<IdentityDBIitializer, LatestUserDBInitializer>();

            // Add application services.
            services.AddTransient<IEmailSender, EmailSender>();

            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IdentityDBIitializer dBInitializer)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseAuthentication();

            //Seeds Identity DB
            dBInitializer.Initialize();

            //UserRoleInitializer.InitializeUsersAndRoles(app.ApplicationServices);

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

2 个答案:

答案 0 :(得分:1)

对于您的问题,原因是您的密码无效导致创建用户失败。然后,await _userManager.FindByNameAsync(user)将返回null而不是预期的User。

您可以尝试使用密码,例如 1qaz @ WSX

您可以参考enter link description here查找默认要求。

答案 1 :(得分:0)

当我在.NET Core 2 Betas上工作时,同样的问题......

这可能意味着凭据不符合您的配置。或者,就我而言,我必须通过IServiceProvider获取dbcontext和管理器。

您可以在配置(...)

结束时执行此操作
// Data seeding
            await Data.DataSeeder.SeedDatabase(app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope());

有一个数据播种器类使用IServiceScope来连接依赖项,poof

public class DataSeeder
    {
        public static async Task SeedDatabase(IServiceScope scope)
        {
            try
            {
                CounterDbContext context = scope.ServiceProvider.GetService<CounterDbContext>();

                CustoUserManager userManager = scope.ServiceProvider.GetRequiredService<CustoUserManager>();
                CustoRoleManager roleManager = scope.ServiceProvider.GetRequiredService<CustoRoleManager>();

                // SEED USER CODE HERE
                // SEED USER CODE HERE
                // SEED USER CODE HERE
                // SEED USER CODE HERE


                if (!context.CurrencyTypes.Any()) {
                        string[,] currencyTypes = new string[,] {
                            { "Crypto", "CRYPTO" },
                            { "Fiat Money", "FIAT" }
                        };

                        for (int i = 0; i < currencyTypes.GetLength(0); i++)
                        {
                            CurrencyType cType = new CurrencyType()
                            {
                                Name = currencyTypes[i, 0],
                                TypeShortForm = currencyTypes[i, 1],
                            };

                            context.CurrencyTypes.Add(cType);
                        }

                        context.SaveChanges(firstUser.Id);
                    }
}
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }

这可能很乱......上面是播种类吧?以下是您为用户执行此操作的方法。

#if DEBUG
                string[] CreateUsers = { "nixholas"};
                string[] CreateNames = { "Nicholas" };
                string[] CreateEmails = { "xxx@xxxx.co" };
                string defaultPassword = "P@ssw0rd";

                // Seed the roles first
                // https://stackoverflow.com/questions/34343599/how-to-seed-users-and-roles-with-code-first-migration-using-identity-asp-net-mvc
                if (!roleManager.Roles.Any())
                {
                    foreach (UserRoleType role in Enum.GetValues(typeof(UserRoleType)))
                    {
                        var newRole = new Role();
                        newRole.Name = role.ToString();
                        await roleManager.CreateAsync(newRole);
                    }
                }

                if (await userManager.FindByEmailAsync(CreateEmails[0]) == null)
                {
                    for (int i = 0; i < CreateUsers.Length; i++)
                    {
                        User user = new User
                        {
                            Email = CreateEmails[i],
                            UserName = CreateUsers[i],
                            Name = CreateNames[i]
                        };

                        await userManager.CreateAsync(user, defaultPassword);

                        // Setup
                        await userManager.UpdateSecurityStampAsync(user);
                        user.NormalizedUserName = user.UserName;
                        user.NormalizedEmail = user.Email;
                        await userManager.UpdateNormalizedUserNameAsync(user);
                        await userManager.UpdateNormalizedEmailAsync(user);
                        await userManager.UpdateAsync(user);

                        // Email Automated Setup
                        var token = await userManager.GenerateEmailConfirmationTokenAsync(user);
                        await userManager.ConfirmEmailAsync(user, token);

                        await userManager.AddToRoleAsync(user, "Owner");
                    }
                }