At the present I am trying to assign a role to a user the role table looks like following
Role Id | Name | NormalizedName |
---|---|---|
59f5238-818e-40f9-b95a-fc65db67f253 | Parent | Parent |
My User table is
Id | First Name | Surname |
---|---|---|
b3e9d5ec-1ddf-4e57-bf00-1afc2e7f0582 | Parent | One |
The role is also being created fine.
But for some reason when I try to add this user to the roles table I am getting the following.
The Task is cancelled at Microsoft.AspNetCore.Identity.UserManager`1.d__116.MoveNext() at Web.SampleData.d__2.MoveNext() in SampleData.cs:line 118
I am using the code to add to the role manager the user
public static async Task<IdentityResult>
AssignRoles(IServiceProvider services,
string email, string[] roles)
{
IdentityResult result = new IdentityResult();
UserManager<ApplicationUser> _userManager =
services.GetService<UserManager<ApplicationUser>>();
ApplicationUser user = await
_userManager.FindByEmailAsync(email);
result = await _userManager.AddToRolesAsync(user, roles);
return result;
}
The role is being passed as "Parent" and the correct email address of [email protected] so why am I getting a task is canceled?
As you see the above user has not been added to the aspnetuseroles table
This is the complete seeding method
public static void CreateParent(IServiceProvider
serviceProvider)
{
var context = new DBContext();//
serviceProvider.GetService<DBContext>();
string[] roles = new string[] { "Parent" };
foreach (string role in roles)
{
var roleStore = new RoleStore<IdentityRole>(context);
if (!context.Roles.Any(r => r.Name == role))
{
roleStore.CreateAsync(new IdentityRole(role));
}
}
var user = new ApplicationUser
{
FirstName = "Parent",
LastName = "One",
Email = "[email protected]",
NormalizedEmail = "[email protected]",
UserName = "[email protected]",
NormalizedUserName = "[email protected]",
PhoneNumber = "+111111111111",
EmailConfirmed = true,
PhoneNumberConfirmed = true,
SecurityStamp = Guid.NewGuid().ToString("D")
};
var db = new DBContext();
if (!db.Users.Any(u => u.UserName == user.UserName))
{
var password = new PasswordHasher<ApplicationUser>);
var hashed = password.HashPassword(user,2
Test12345!");
user.PasswordHash = hashed;
var userStore = new UserStore<ApplicationUser>
(context);
var result = userStore.CreateAsync(user);
}
AssignRoles(serviceProvider, user.Email, roles);
db.SaveChangesAsync();
}
I call it from my web app startup.cs as such
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env,IServiceProvider service)
{
SampleData.CreateParent(service);
}
The reason why it is getting Cancelled is that you have an asynchronous call that you haven't actually added await to them.
You have async methods in your CreateParent function so you need to set it as
public async Task CreateParent()
and you need to add await on
await roleStore.CreateAsync(new IdentityRole(role));
await db.SaveChangesAsync();
public async Task Configure(IApplicationBuilder app,
IWebHostEnvironment env,IServiceProvider service)
{
await SampleData.CreateParent(service);
}
I suggest you add it in the Program.cs
public class Program
{
public static async Task Main(string[] args)
{
new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var host = await CreateHostBuilder(args).Build().MigrateAndSeedDataAsync();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).UseDefaultServiceProvider(options => options.ValidateScopes = false);
}