Search code examples
c#.netasp.net-coreasp.net-identityasp.net-core-webapi

An error occurred while accessing the Microsoft.Extensions.Hosting services when doing migrations and customisingasp.net user and roles tables


An error occurred while accessing the Microsoft.Extensions.Hosting services when doing migrations and customisingasp.net user and roles tables

I am using .Net 6 and I am trying to customise the roles tables so that it caters for some extra columns The project builds however when I try to add an initial migrationI get an erorr

An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: GenericArguments[0], 'Microsoft.AspNetCore.Identity.IdentityUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TUser'.

I think were I am going wrong is the ApplicationDbContext base class and the way I am ordering all the generic parameters

Custom user class with extra fields

namespace AngularAuthAPI.Models.Authentication
{
    public class UserInformation: IdentityUser<Guid>
    {
        public int CenterID { get; set; }
            /*public int UserName { get; set; }
            public string Name { get; set; }
            public string Surname { get; set; }
            public string Password { get; set; }
            public string UserEmailAddress { get; set; }
            public string ContactDetails { get; set; }*/
            
        public int NumberOfCandidates { get; set; }
        public bool Approved { get; set; }
        public bool TermsAndConditions { get; set; }
        public DateTime Modified { get; set; }
        public int CenterType { get; set; }
        public bool IsActive { get; set; }
        public bool IsSchoolAdmin { get; set; }
    }
}

Custom role class with extra fields

namespace AngularAuthAPI.Models.Authentication
{
    public class ApplicationRole: IdentityRole<Guid>
    {
        public ApplicationRole() : base()
        { }
        public ApplicationRole(string name) : base(name)
        { }
        public string? RoleDescription { get; set; }
        public string? RoleName { get; set; }
        
        public int RoleID { get; set; }
        public int CenterID { get; set; }

    }
}

ApplicationDbContext with role

namespace AngularAuthAPI.Models
{
    public class ApplicationDbContext : IdentityDbContext<UserInformation,  ApplicationRole, Guid>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
            {

            }
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
        }
        
        /*private void SeedRoles (ModelBuilder builder)
        {
            builder.Entity<ApplicationRole>().HasData
            (
               new IdentityRole() { Name = "Invigilator", ConcurrencyStamp = "1", NormalizedName = "Invigilator" },
                new IdentityRole() { Name = "Student", ConcurrencyStamp = "2", NormalizedName = "Student" },
               new IdentityRole() { Name = "SuperAdmin", ConcurrencyStamp = "3", NormalizedName = "SuperAdmin" }
            ); 
       }*/
    }

}

Program.cs to register services

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var configuration = builder.Configuration;
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"))); 

    builder.Services.AddIdentity<IdentityUser, ApplicationRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

// Adding Authentication

Solution

  • In your question, you custom IdentityUser, IdentityRole class and Change the primary key type, So here you need to add Identity in Program.cs like this:

    builder.Services.AddIdentity<UserInformation, ApplicationRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultUI()
                .AddDefaultTokenProviders();
    

    Now Database can be created successfully

    enter image description here

    You can also refer to this Docs to learn more.