0

I had to extend IdentityUser model (and AspNetUser table of course) with some extra field (RegistrationDate) so I created ExtendIdentityUser model class. It works nice.

Then, I needed to change some user default fields (UserName and Email) to required ones. After this change method await userManager.FindByEmailAsync("[email protected]"); started returns user object with empty username and email fields. Rest of them are properly fullfileed, even NormalizedUserName and NormalizedEmail. Before making UserName and Email to required it worked properly.

My custom model class looks like:

public class ExtendedIdentityUser : IdentityUser
{
    public override string UserName { get; set; } = string.Empty;
    public override string Email { get; set; } = string.Empty;
    public DateTime RegistrationDate { get; set; }
}

My custom map model class is:

public class ExtendedIdentityUserMap : IEntityTypeConfiguration<ExtendedIdentityUser>
{
    public void Configure(EntityTypeBuilder<ExtendedIdentityUser> builder)
    {
        // Properties
        builder.Property(u => u.UserName).HasColumnName("UserName").IsRequired();
        builder.Property(u => u.Email).HasColumnName("Email").IsRequired();
        builder.Property(u => u.RegistrationDate).IsRequired();
        
        // Default values
        builder.Property(u => u.RegistrationDate).HasDefaultValueSql("GETDATE()")
    }
}

ApplicationDbContext was also updated with my map class:

public class ApplicationDbContext(DbContextOptions options) : IdentityDbContext(options)
{
    public DbSet<ExtendedIdentityUser> ExtendedIdentityUsers { get; set; }
    // another tables
    
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.ApplyConfiguration(new ExtendedIdentityUserMap());
        // another mappings
    }
}

Generated migrations code looks good:

protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AlterColumn<string>(
                name: "UserName",
                table: "AspNetUsers",
                type: "nvarchar(256)",
                maxLength: 256,
                nullable: false,
                defaultValue: "",
                oldClrType: typeof(string),
                oldType: "nvarchar(256)",
                oldMaxLength: 256,
                oldNullable: true);

            migrationBuilder.AlterColumn<string>(
                name: "Email",
                table: "AspNetUsers",
                type: "nvarchar(256)",
                maxLength: 256,
                nullable: false,
                defaultValue: "",
                oldClrType: typeof(string),
                oldType: "nvarchar(256)",
                oldMaxLength: 256,
                oldNullable: true);
        }

Changes are appiled successfully to my local DB - columns UserName and Email became non nullable. Data is there. But calling await userManager.FindByEmailAsync("[email protected]"); returns user object with empty username and email fields.

My question is: what am I missing? Why username and email fields are empty for my user object?

If it's possible I would like to avoid implement own userManager as a solution.

@EDIT I had investigated it deeply, and I discovered that property Users in Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore already contains list of users without filled email and username fields. That's why the method FindByEmailAsync() from userManager returns not completed data as well, because it uses UserStore class for obtaining userData.

6
  • 1
    I do not have much experience with asp.net identity but can you try by removing default initialization of both the property (string.Empty) from ExtendedIdentityUser class. Commented Jan 20 at 14:19
  • Your exact code works on my end. await userManager.FindByEmailAsync("[email protected]"); returns both username and email fields with value. Did you override anything else? Commented Jan 20 at 18:41
  • Removing default initialization didn't help. Also, I do not override anything else. Commented Jan 21 at 9:31
  • First, please check the data table in database make sure the username and email are not empty. Second, try to use ApplicationDbContext to query the ExtendedIdentityUsers, whether you can get the username and email or not? Commented Jan 23 at 5:53
  • I've checked table and username and email are not empty. Running SQL query in Microsoft SQL Server Management Studio returns this data properly. I've also tried to use ApplicationDbContext to query the ExtendedIdentityUsers and for this case email and username are empty :( But the normalized columns are fullfiled. Commented Jan 24 at 10:09

1 Answer 1

1

Please check your Identity Configuration code, you are using the following code to configure the Identity, right?

builder.Services.AddDefaultIdentity<ExtendedIdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();  

After testing it with your custom model class and ApplicationDbContext, I reproduce the problem, when query the data using usermanager, the result is null, even though the data exists.

As you said, the issue relates the UserStore, in the deeply, it might still using the IdentityUser.

To solve this issue, you can modify the ApplicationDbContext as below: use IdentityDbContext<ExtendedIdentityUser>:

public class ApplicationDbContext : IdentityDbContext<ExtendedIdentityUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
    public DbSet<WebApplication5.Models.Product> Product { get; set; } = default!;

    public DbSet<ExtendedIdentityUser> ExtendedIdentityUsers { get; set; }
    // another tables

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.ApplyConfiguration(new ExtendedIdentityUserMap());
        // another mappings
    }
}

It will specify the ExtendedIdentityUser class as the default user class. So, when query the data via usermanager, the result as below:

success

Reference link: Custom user data.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes! This was my case. After updating ApplicationDbContext class with IdentityDbContext<ExtendedIdentityUser>, properties username and email are properly filled with data. Thank you very much :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.