Search code examples
c#asp.net-coreasp.net-core-mvcasp.net-core-identity

How to change the type of the user's id from string to int in Asp.NET Core 2.2?


I have an application written using C# on the top on Asp.Net Core 2.2. The application was written on the top of Core 2.1 but then upgraded to Asp.net Core 2.2.

Now, I decided to change the Id type of the User model from string to an integer.

To override the string/default type, I created a User class like so

public class User : IdentityUser<int>
{
}

Then I created a Role class like so

public class Role : IdentityRole<int>
{
}

Finally, I updated the ApplicationDbContext class like so

public class ApplicationDbContext : IdentityDbContext<User, Role, int>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Then I deleted all the database tables that start with AspNet and the _Migrations table.

Now, every time I run my app I get the following error

InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' has been registered.

Here is my Startup.cs class

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));


        services.AddDefaultIdentity<User>().AddEntityFrameworkStores<ApplicationDbContext>()
          .AddDefaultTokenProviders();

    services.AddAuthentication()
            .AddFacebook(facebookOptions =>
    {
        facebookOptions.AppId = Configuration["Authentication:Facebook:AppId"];
        facebookOptions.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
    });

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

I also tried to so the following code in my Startsup file

services.AddScoped<UserManager<User>>();

Here is a screenshot of the stack trace enter image description here


Solution

  • The call to AddDefaultIdentity<TUser>() registers UserManager<TUser> with the Dependency Injection container. Before you created your own custom TUser type, you would have been using IdentityUser here, which would have registered UserManager<IdentityUser>.

    With the change from using IdentityUser to using User, you now register UserManager<User> instead of UserManager<IdentityUser>. The error message from your question shows that a partial view within your project is attempting to receive an instance of UserManager<IdentityUser> from the DI container, but it should be requesting an instance of UserManager<User> due to your change. That means the following change would be needed in the partial view:

    @inject UserManager<IdentityUser> UserManager
    

    -becomes-

    @inject UserManager<User> UserManager
    

    This will fix the specific error you've shown, but you'll also need to scan through the rest of the project to see if there are any other references to UserManager<IdentityUser> that also need to be changed.