Search code examples
asp.net-identityasp.net-core-webapiasp.net-core-3.0

Seeding database via middleware pipeline throws an exception asp.net core


I have 3 layers in my solution. The Core, BLL, and DAL layers. All are class libraries with the exception of the Core layer which is a web API layer. The DAL layer has the context, seeder, migrations, entity, and repository classes. I'm using ASP.NET Core 3.0 Preview for the Core layer and .net standard 2.0 for the class library layers. The Seed method in the seeder class is async returning a Task. When the Core project is run, I get this exception:

enter image description here

When I remove the .Wait() method call there is no exception thrown and the API works fine, but the database is not seeded.

How do I fix this? Thanks.

Startup.cs Middleware pipeline:

     public void Configure(IApplicationBuilder app, IWebHostEnvironment env, BlazeMartDbSeeder seeder)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //throws exception here
            seeder.Seed().Wait();

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });


        }

seeder class:

using BlazeMartManagementSystem.DAL.Entities;
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace BlazeMartManagementSystem.DAL
{
    public class BlazeMartDbSeeder
    {
        private RoleManager<IdentityRole> _roleMgr;
        private UserManager<ApplicationUser> _userMgr;

        public BlazeMartDbSeeder(UserManager<ApplicationUser> userMgr, RoleManager<IdentityRole> roleMgr)
        {
            _userMgr = userMgr;
            _roleMgr = roleMgr;
        }

        public async Task Seed()
        {
            var user = await _userMgr.FindByNameAsync("Raj");

            // Add User
            if (user == null)
            {
                if (!(await _roleMgr.RoleExistsAsync("Manager")))
                {
                    var role = new IdentityRole("Manager");
                    await _roleMgr.AddClaimAsync(role, new Claim(type: "IsManager", value: "True"));
                    await _roleMgr.CreateAsync(role);
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });

                }

                user = new ApplicationUser
                {
                    UserName = "raj",
                    FirstName = "Raj",
                    LastName = "Narayanan",
                    Email = "[email protected]"
                };

                var userResult = await _userMgr.CreateAsync(user, "Asp3raj");
                var roleResult = await _userMgr.AddToRoleAsync(user, "Manager");
                var claimResult = await _userMgr.AddClaimAsync(user, new Claim("GreenBadge", "True"));

                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }

            user = await _userMgr.FindByNameAsync("Shawnw");

            // Add User
            if (user == null)
            {
                if (!(await _roleMgr.RoleExistsAsync("Employee")))
                {
                    var role = new IdentityRole("Employee");
                    await _roleMgr.AddClaimAsync(role, new Claim(type: "IsEmployee", value: "True"));
                    await _roleMgr.CreateAsync(role);
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });

                }

                user = new ApplicationUser
                {
                    UserName = "shawnw",
                    FirstName = "Shawn",
                    LastName = "Wildermuth",
                    Email = "[email protected]"
                };

                var userResult = await _userMgr.CreateAsync(user, "P@ssw0rd!");
                var roleResult = await _userMgr.AddToRoleAsync(user, "Employee");
                var claimResult = await _userMgr.AddClaimAsync(user, new Claim("OrangeBadge", "True"));

                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }

            user = await _userMgr.FindByNameAsync("John");

            // Add User
            if (user == null)
            {
                if (!(await _roleMgr.RoleExistsAsync("Vendor")))
                {
                    var role = new IdentityRole("Vendor");
                    await _roleMgr.AddClaimAsync(role, new Claim(type: "IsVendor", value: "True"));
                    await _roleMgr.CreateAsync(role);
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });

                }

                user = new ApplicationUser
                {
                    UserName = "johng",
                    FirstName = "John",
                    LastName = "Galli",
                    Email = "[email protected]"
                };

                var userResult = await _userMgr.CreateAsync(user, "P@ssw0rd!");
                var roleResult = await _userMgr.AddToRoleAsync(user, "Vendor");
                var claimResult = await _userMgr.AddClaimAsync(user, new Claim("BlueBadge", "True"));

                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }

        }
    }
}

Solution

  • You could try to define the seeder class like below :

    public static class BlazeMartDbSeeder
    {
        public static void Seed(UserManager<ApplicationUser> userMgr, RoleManager<IdentityRole> roleMgr)
        {
            //var user =  userMgr.FindByNameAsync("Raj");
    
            // Add User
            if (userMgr.FindByNameAsync("Raj").Result == null)
            {
                if (!( roleMgr.RoleExistsAsync("Manager").Result))
                {
                    IdentityRole role = new IdentityRole();
                    role.Name = "Manager";
                    IdentityResult result = roleMgr.CreateAsync(role).Result;
                    IdentityResult claim=roleMgr.AddClaimAsync(role, new Claim(type: "IsManager", value: "True")).Result;
    
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });
    
                }
    
                ApplicationUser user = new ApplicationUser
                {
                    UserName = "raj",
                    FirstName = "Raj",
                    LastName = "Narayanan",
                    Email = "[email protected]"
                };
    
                IdentityResult userResult =  userMgr.CreateAsync(user, "Asp3raj#").Result;
                IdentityResult roleResult =  userMgr.AddToRoleAsync(user, "Manager").Result;
                IdentityResult claimResult =  userMgr.AddClaimAsync(user, new Claim("GreenBadge", "True")).Result;
    
                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }
    
            //user =  userMgr.FindByNameAsync("Shawnw");
    
            // Add User
            if (userMgr.FindByNameAsync("Shawnw").Result == null)
            {
                if (!(roleMgr.RoleExistsAsync("Employee").Result))
                {
                    IdentityRole role = new IdentityRole();
                    role.Name = "Employee";
                    IdentityResult result=roleMgr.CreateAsync(role).Result;
                    IdentityResult claim =roleMgr.AddClaimAsync(role, new Claim(type: "IsEmployee", value: "True")).Result;
    
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });
    
                }
    
                ApplicationUser user = new ApplicationUser
                {
                    UserName = "shawnw",
                    FirstName = "Shawn",
                    LastName = "Wildermuth",
                    Email = "[email protected]"
                };
    
                IdentityResult userResult = userMgr.CreateAsync(user, "P@ssw0rd!").Result;
                IdentityResult roleResult = userMgr.AddToRoleAsync(user, "Employee").Result;
                IdentityResult claimResult = userMgr.AddClaimAsync(user, new Claim("OrangeBadge", "True")).Result;
    
                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }
    
            // user =  userMgr.FindByNameAsync("John");
    
            // Add User
            if (userMgr.FindByNameAsync("John").Result == null)
            {
                if (!(roleMgr.RoleExistsAsync("Vendor").Result))
                {
                    IdentityRole role = new IdentityRole();
                    role.Name = "Vendor";
                    IdentityResult result = roleMgr.CreateAsync(role).Result;
                    IdentityResult claim= roleMgr.AddClaimAsync(role, new Claim(type: "IsVendor", value: "True")).Result;
    
                    //  role.Claims.Add(new IdentityRoleClaim<string>() { ClaimType = "IsManager", ClaimValue = "True" });
    
                }
    
                ApplicationUser user = new ApplicationUser
                {
                    UserName = "johng",
                    FirstName = "John",
                    LastName = "Galli",
                    Email = "[email protected]"
                };
    
                IdentityResult userResult = userMgr.CreateAsync(user, "P@ssw0rd!").Result;
                IdentityResult roleResult = userMgr.AddToRoleAsync(user, "Vendor").Result;
                IdentityResult claimResult = userMgr.AddClaimAsync(user, new Claim("BlueBadge", "True")).Result;
    
                if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
                {
                    throw new InvalidOperationException("Failed to build user and roles");
                }
            }
    
        }
    }
    

    Startup.cs

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, UserManager<ApplicationUser> userMgr, RoleManager<IdentityRole> roleMgr)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
    
            BlazeMartDbSeeder.Seed(userMgr, roleMgr);
    
            app.UseHttpsRedirection();
    
            app.UseRouting();
    
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    

    Note: The components of the password contain uppercase and lowercase letters, numbers and special symbols.

    About Seed Users And Roles Data In ASP.NET Core Identity , you could refer to here .