-
-
Save mombrea/9a49716841254ab1d2dabd49144ec092 to your computer and use it in GitHub Desktop.
| using Microsoft.AspNetCore.Identity; | |
| using Microsoft.AspNetCore.Identity.EntityFrameworkCore; | |
| using System.Linq; | |
| namespace My.App.Data | |
| { | |
| public class DbInitializer : IDbInitializer | |
| { | |
| private readonly ApplicationDbContext _context; | |
| private readonly UserManager<ApplicationUser> _userManager; | |
| private readonly RoleManager<IdentityRole> _roleManager; | |
| public DbInitializer( | |
| 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"); | |
| } | |
| } | |
| } |
| namespace My.App.Data | |
| { | |
| public interface IDbInitializer | |
| { | |
| void Initialize(); | |
| } | |
| } |
| using Microsoft.AspNetCore.Builder; | |
| using Microsoft.AspNetCore.Hosting; | |
| using Microsoft.AspNetCore.Identity.EntityFrameworkCore; | |
| using Microsoft.EntityFrameworkCore; | |
| using Microsoft.Extensions.Configuration; | |
| using Microsoft.Extensions.DependencyInjection; | |
| using Microsoft.Extensions.Logging; | |
| using My.App.Data; | |
| namespace My.App.Admin | |
| { | |
| public class Startup | |
| { | |
| public Startup(IHostingEnvironment env) | |
| { | |
| var builder = new ConfigurationBuilder() | |
| .SetBasePath(env.ContentRootPath) | |
| .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) | |
| .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); | |
| if (env.IsDevelopment()) | |
| { | |
| // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709 | |
| builder.AddUserSecrets<Startup>(); | |
| } | |
| builder.AddEnvironmentVariables(); | |
| Configuration = builder.Build(); | |
| } | |
| public IConfigurationRoot Configuration { get; } | |
| // This method gets called by the runtime. Use this method to add services to the container. | |
| public void ConfigureServices(IServiceCollection services) | |
| { | |
| // Add framework services. | |
| services.AddDbContext<ApplicationDbContext>(options => | |
| options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); | |
| services.AddIdentity<ApplicationUser, IdentityRole>() | |
| .AddEntityFrameworkStores<ApplicationDbContext>() | |
| .AddDefaultTokenProviders(); | |
| services.AddMvc(); | |
| // Add Database Initializer | |
| services.AddScoped<IDbInitializer, DbInitializer>(); | |
| // Add application services. | |
| services.AddTransient<IEmailSender, AuthMessageSender>(); | |
| services.AddTransient<ISmsSender, AuthMessageSender>(); | |
| } | |
| // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
| public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IDbInitializer dbInitializer) | |
| { | |
| loggerFactory.AddConsole(Configuration.GetSection("Logging")); | |
| loggerFactory.AddDebug(); | |
| if (env.IsDevelopment()) | |
| { | |
| app.UseDeveloperExceptionPage(); | |
| app.UseDatabaseErrorPage(); | |
| // Browser Link is not compatible with Kestrel 1.1.0 | |
| // For details on enabling Browser Link, see https://go.microsoft.com/fwlink/?linkid=840936 | |
| // app.UseBrowserLink(); | |
| } | |
| else | |
| { | |
| app.UseExceptionHandler("/Home/Error"); | |
| } | |
| app.UseStaticFiles(); | |
| app.UseIdentity(); | |
| //Generate EF Core Seed Data | |
| dbInitializer.Initialize(); | |
| // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715 | |
| app.UseMvc(routes => | |
| { | |
| routes.MapRoute( | |
| name: "default", | |
| template: "{controller=Home}/{action=Index}/{id?}"); | |
| }); | |
| } | |
| } | |
| } |
I was also having issues with System.ObjectDisposedException: 'Cannot access a disposed object.' and eventually went with a new approach that uses an IWebHost extension off of ASP.Net Core 2.x.
I get rid of System.ObjectDisposedException: 'Cannot access a disposed object.' when I change this:
_context.Database.EnsureCreated();
await _roleManager.CreateAsync(new IdentityRole("Administrator"));
await _userManager.CreateAsync(new ApplicationUser { UserName = user, Email = user, EmailConfirmed = true}, password);
to this:
_context.Database.Migrate();
_roleManager.CreateAsync(new IdentityRole("Administrator")).GetAwaiter().GetResult();
_userManager.CreateAsync(new ApplicationUser { UserName = user, Email = user, EmailConfirmed = true }, password).GetAwaiter().GetResult();
In DoTNet Core 2.0 when I try and run this I get an error on the user creation that says "Value cannot be Null". I am guessing the last line of the initializer:
await _userManager.AddToRoleAsync(await _userManager.FindByNameAsync(user), "Administrator");
has a problem finding the user, but I cannot figure out why. Any ideas?
@daveinyyc can you post rest of your code?
It was because the password listed in this code is not complex enough @ibro, DotNet 2.0 adds some password complexity requirements obviously. Now I have fixed that and the user is creating, but i am getting the dispose error the other commentators mentioned. going to try the GetAwaiter().GetResult() statements like @Planche95 mentions in his comment
The example works if you change the interface to return type Task instead of type void.
namespace My.App.Data { public interface IDbInitializer { Task Initialize(); } }
Also use public async Task Initialize() inside DbInitializer.
@ych-szh You are amazing. Thank you! What exactly does using this scope achieve?