Search code examples
c#entity-framework-6asp.net-web-api2asp.net-identity-2

How to run code within Seed method during deployment?


I have a Web Api solution that makes use of ASP.NET Identity (v2.1) and Entity Framework v6.1. Inside the Seed() method of the Configuration.cs file I have code that creates my first Identity user. This code makes use of the Identity framework to hash the password, create the security stamp, etc. These are all things I cannot do via SQL so adding to the Up() method does not seem like an option.

protected override void Seed(ApplicationDbContext context)
{
    // Create the admin user
    var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

    var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

    var user = new ApplicationUser()
    {
        UserName = "adminuser",
        Email = "adminuser@mycompany.com",
        EmailConfirmed = true,
        FirstName = "John",
        LastName = "Does",
        JoinDate = DateTime.Now.AddYears(-1)
    };

    manager.Create(user, "SuperSecurePassword321!");

    if (roleManager.Roles.Count() == 0)
    {
        roleManager.Create(new IdentityRole { Name = "Admin" });
        roleManager.Create(new IdentityRole { Name = "Employee" });
        roleManager.Create(new IdentityRole { Name = "Customer" });
    }

    var adminUser = manager.FindByName("adminuser");

    manager.AddToRoles(adminUser.Id, new string[] { "Admin" });
}

I need to use FTP to publish this (no control over this). Any suggestions on how to run this code once it is deployed and the database is schema is setup?

Options I have considered:

  1. I have thought about creating an API endpoint that when called can kick off this code, however, this endpoint would have to allow anonymous access since it would be creating this first user and the roles used in the system. I would then need to somehow disable or remove this endpoint later.
  2. Script the database and include the data and then restore that to the database server targeted for deployment.

Solution

  • Seed() gets called when the database is accessed the first time. What's wrong with that automatic behavior?

    If you want to call it manually, try something like this in protected void Application_Start():

    Database.SetInitializer(new YourInititalizer());
    var dbContext = new TheContextYouAreUsing();
    dbContext.Database.Initialize(force: true);