Search code examples
c#asp.net-core.net-core-3.0ef-core-3.0

Getting a task was canceled error when trying to seed roles in .NET Core 3.0


In my .NET Core 3.0 application, I'm trying to seed new roles and users into the database the first time the application executes and connects to the database.

So I've written this simple class:

public static class UserAndRoleDataInitializer
{
    public static void SeedData(UserManager<AppUser> userManager, RoleManager<IdentityRole<Guid>> roleManager)
    {
        SeedRoles(roleManager);
        SeedUsers(userManager);
    }

    private static async void SeedRoles(RoleManager<IdentityRole<Guid>> roleManager)
    {           
        var exists = await roleManager.RoleExistsAsync("administrator");
        if (!exists)
        {               
            await roleManager.CreateAsync(new IdentityRole<Guid>("administrator"));
        }

        exists = await roleManager.RoleExistsAsync("editor");
        if (!exists)
        {
            await roleManager.CreateAsync(new IdentityRole<Guid>("editor"));
        }
    }

    ...
}

which is invoked from Program.cs:

var userManager = serviceProvider.GetRequiredService<UserManager<AppUser>>();
var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole<Guid>>>();
UserAndRoleDataInitializer.SeedData(userManager, roleManager);

Each time SeedData is executed I get the following error:

System.Threading.Tasks.TaskCanceledException: 'A task was canceled.'

on the first line of SeedRoles: var exists = await roleManager.RoleExistsAsync("administrator");

I've researched the web trying to find some answers but couldn't find anything similar to my use case. Any help would be greatly appreciated.


Solution

  • The comments from @Guilherme were really very helpful.

    This is what I did to get it work:

    public static class UserAndRoleDataInitializer
    {
        public static async Task<IdentityResult> SeedData(UserManager<AppUser> userManager, RoleManager<IdentityRole<Guid>> roleManager)
        {
            await SeedRoles(roleManager);
            await SeedUsers(userManager);
    
            return IdentityResult.Success;
        }
    
        private static async Task<IdentityResult> SeedRoles(RoleManager<IdentityRole<Guid>> roleManager)
        {                       
            var exists = await roleManager.RoleExistsAsync("Administrator");
            if (!exists)
            {               
                await roleManager.CreateAsync(new IdentityRole<Guid>("Administrator"));
            }
            ...
            return IdentityResult.Success;
        }
    
        private static async Task<IdentityResult> SeedUsers(UserManager<AppUser> userManager)
        {            
            var usr = await userManager.FindByNameAsync("admin");
            if (usr == null)
            {
                AppUser user = new AppUser
                {
                    UserName = "admin",
                    Email = "[email protected]",
                    FirstName = "Giorgos",
                    LastName = "Betsos"
                };
    
                IdentityResult result = await userManager.CreateAsync(user, "P@ssw0rd1!");
    
                if (result.Succeeded)
                {
                    await userManager.AddToRoleAsync(user, "Administrator");
                }
            }
    
            return IdentityResult.Success;
        } 
    }
    

    Last, but not least, this is how SeedData is invoked from Main:

     UserAndRoleDataInitializer.SeedData(userManager, roleManager).Wait();