Пользователь и роли DotNet Core 2 Seed

Использование шаблона, встроенного в VS2017 для Core 2 MVC с аутентификацией. Попытка заполнить базу данных пользователями и ролями. Роли работают хорошо, они сеют. Пользователи всегда возвращают сообщение об ошибке «Не может быть NULL», я думаю, это потому, что эта строка в конце функции инициализации не может найти пользователя.

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

Я использовал этот пост, чтобы создать его: https://gist.github.com/mombrea/9a49716841254ab114d2cdabd >

ПРИМЕЧАНИЕ. Этот пост предназначен для 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 = "[email protected]";
            string password = "z0mgchangethis";
            await _userManager.CreateAsync(new ApplicationUser { UserName = user, Email = user, EmailConfirmed = true }, password);
            await _userManager.AddToRoleAsync(await _userManager.FindByNameAsync(user), "Administrator");
        }
    }

Вот мой стартап:

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?}");
            });
        }
    }

person dave317    schedule 01.03.2018    source источник
comment
Одно из ваших полей в ApplicationUser не должно быть пустым, поэтому Cannot be NULL, вероятно, нужно посмотреть, какое из них требуется.   -  person mvermef    schedule 02.03.2018
comment
попробуйте этот пароль, P@ssw0rd!, или вы можете настроить пользовательские параметры в своем запуске, чтобы получить любой тип пароля, который вы хотите.   -  person Sabir Hossain    schedule 02.03.2018


Ответы (2)


Для вашей проблемы это вызвано тем, что ваш пароль недействителен, что приводит к сбою создавшего пользователя. Тогда await _userManager.FindByNameAsync(user) вернет null вместо ожидаемого пользователя.

Вы можете попробовать ввести пароль, например 1qaz @ WSX.

Вы можете сослаться на введите здесь описание ссылки, чтобы узнать требования по умолчанию.

person Edward    schedule 02.03.2018
comment
Это заставило пользователя создать, теперь я получаю сообщение об ошибке: - person dave317; 03.03.2018
comment
Эта ошибка: System.ObjectDisposedException: 'Невозможно получить доступ к удаленному объекту.', Это указано в ссылке githib, поэтому я собираюсь попробовать некоторые решения оттуда - person dave317; 03.03.2018

wew, такая же проблема, когда я работал над .NET Core 2 Betas ...

Это может означать, что учетные данные не соответствуют вашим настройкам. Или, в моем случае, мне пришлось получить dbcontext и менеджеры через IServiceProvider.

Вы можете сделать это в конце Настроить (...)

// 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 = { "[email protected]" };
                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");
                    }
                }
person Nicholas    schedule 09.03.2018
comment
Спасибо @nicholas. Я собираюсь попробовать, это решение выглядит немного элегантнее, чем то, что я сделал. Я все еще пытаюсь сосредоточиться на внедрении зависимостей и iserviceproviders, я всего лишь промежуточный разработчик. Мое решение сработало, но мне оно кажется беспорядочным. - person dave317; 12.03.2018