I don't understand a lot about Identity Framework but it seems like the problem arises when I have multiple AddIdentity calls.
Yes, you are right, the issue relates the multiple AddIdentity(). You cannot repeatedly use AddIdentity
to add an identity. ASP.NET Core provides a built-in method: AddIdentityCore<TUser>
. Code like this:
builder.Services.AddDefaultIdentity<Account>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddIdentityCore<Customer>().AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddIdentityCore<Professional>().AddEntityFrameworkStores<ApplicationDbContext>();
The detail sample code as below:
Model:
public class Account : IdentityUser
{
public string FullName { get; set; } = string.Empty;
public string ImageUrl { get; set; } = string.Empty;
public bool HasAcceptedTermsOfUse { get; set; } = default;
}
public class Customer : Account
{
// Customer specific properties
public string CustomInfo { get; set; }
}
public class Professional : Account
{
// Professional specific properties
public string PerfessionalInfo { get; set; }
}
DbContext:
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Professional> Professionals { get; set; }
public DbSet<Account> Accounts { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Account>(entity => { entity.ToTable("Accounts"); });
builder.Entity<Customer>(entity => { entity.ToTable("Customers"); });
builder.Entity<Professional>(entity => { entity.ToTable("Professionals"); });
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Program.cs:
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<Account>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddIdentityCore<Customer>().AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddIdentityCore<Professional>().AddEntityFrameworkStores<ApplicationDbContext>();
Then in the controller, use the following code to use the Identity:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly UserManager<Customer> _customerManaer;
private readonly UserManager<Professional> _promanager;
public HomeController(ILogger<HomeController> logger, UserManager<Customer> customerusermanager, UserManager<Professional> promanager)
{
_logger = logger;
_customerManaer = customerusermanager;
_promanager=promanager;
}
public async Task<IActionResult> Index()
{
var cusomer = new Customer() { Email="cutomer1@hotmail.com", UserName="Tom", FullName="Ton L", CustomInfo="customer information"};
var result = await _customerManaer.CreateAsync(cusomer, "Password01!");
var professional = new Professional() { Email="pro1@hotmail.com", UserName="Jack", FullName="Jack.D", PerfessionalInfo="hello" };
var result2 = await _promanager.CreateAsync(professional, "Password01!");
return View();
}
The result as below:
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion