Skip to content

Instantly share code, notes, and snippets.

@mombrea
Last active April 5, 2023 21:55
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mombrea/9a49716841254ab1d2dabd49144ec092 to your computer and use it in GitHub Desktop.
Save mombrea/9a49716841254ab1d2dabd49144ec092 to your computer and use it in GitHub Desktop.
EF Core 1.0 and ASP.NET Core Identity Seed Data
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 = "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");
}
}
}
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?}");
});
}
}
}
@grumson
Copy link

grumson commented Sep 8, 2017

Hi!

when I run this code I get:
System.ObjectDisposedException: 'Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.'

On class DbInitializer : IDbInitializer line 38
Can you please help me!

@ych-szh
Copy link

ych-szh commented Sep 21, 2017

@Supratentorial
Copy link

@ych-szh You are amazing. Thank you! What exactly does using this scope achieve?

@ebello
Copy link

ebello commented Oct 19, 2017

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.

@Planche95
Copy link

Planche95 commented Jan 8, 2018

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

@daveinyyc
Copy link

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?

@Ibro
Copy link

Ibro commented Mar 2, 2018

@daveinyyc can you post rest of your code?

@daveinyyc
Copy link

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

@imrenuijen
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment