การขยาย EF Core Identity UserStore ด้วย ID ผู้ใช้จำนวนเต็ม

การใช้เซิร์ฟเวอร์ Blazor, dotnet 5 และ Entity Framework Core ฉันปรับแต่ง Identity ได้สำเร็จโดยใช้ ID จำนวนเต็ม

e.g

public class ApplicationUser : IdentityUser<int>
{
    [Required]
    [MaxLength(50)]
    public string FirstName { get; set; }

    [Required]
    [MaxLength(50)]
    public string LastName { get; set; }
}

ตอนนี้ฉันต้องการขยาย UserStore สำหรับการเข้าสู่ระบบแบบกำหนดเองเพื่อจัดเก็บประวัติรหัสผ่านเพื่อป้องกันการทำซ้ำ ดูเหมือนว่าเอกสารวิธีการทำสิ่งนี้จะเป็น:

public class ApplicationUserStore : UserStore<ApplicationUser>
{
    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }

    public override async Task<IdentityResult> CreateAsync(ApplicationUser appUser)
    {
        await base.CreateAsync(appUser);
        await AddToUsedPasswordAsync(appUser, appUser.PasswordHash);
    }

    public Task AddToUsedPasswordAsync(ApplicationUser appuser, string userpassword)  
    {  
        appuser.UserUsedPassword.Add(new UsedPassword() { UserID = appuser.Id, HashPassword = userpassword });  
        return UpdateAsync(appuser);  
    } 
} 

สิ่งนี้ใช้ได้กับ GUID Id เริ่มต้น แต่เมื่อใช้จำนวนเต็มจะเกิดข้อผิดพลาด:

ประเภท ApplicationUser ไม่สามารถใช้เป็นพารามิเตอร์ประเภท 'TUser' ในประเภททั่วไปหรือวิธีการ 'UserStore' ไม่มีการแปลงการอ้างอิงโดยนัยจาก ApplicationUser' เป็น 'Microsoft.AspNetCore.Identity.IdentityUser'

วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร?

แก้ไข:

ต่อ @Yinqiu แก้ไขสำหรับ ApplicationRole ที่กำหนดเองเป็น

ApplicationUserStore ระดับสาธารณะ: UserStore {

    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }

สร้างสำเร็จและสร้างผู้ใช้ แต่ให้ข้อผิดพลาดรันไทม์เมื่อพยายามเข้าถึง ApplicationUserManager.IsInRoleAsync:

{ไม่สามารถสร้าง DbSet สำหรับ 'IdentityUserRole' ได้เนื่องจากประเภทนี้ไม่รวมอยู่ในโมเดลสำหรับบริบท}

อย่างไรก็ตาม ฉันมีบทบาทผู้ใช้ที่กำหนดเอง:

public class ApplicationUserRole : IdentityUserRole<int>
{
    public ApplicationUserRole() : base() { }

    public bool IsSystemEssential { get; set; }

}

ด้วยคำจำกัดความใน ApplicationDbContext :

DbSet ApplicationUserRoles สาธารณะ { รับ; ชุด; }


comment
สวัสดี @MaxTheCoder มีการอัปเดตอะไรบ้าง?   -  person Yinqiu    schedule 16.04.2021
comment
นี่ไม่ใช่ฟอรัม โปรดอย่าเพิ่มวิธีแก้ปัญหาให้กับคำถาม โพสต์คำตอบหากคุณต้องการระบุว่าคุณพบคำตอบอื่นนอกเหนือจากที่โพสต์ไปแล้ว   -  person Camilo Terevinto    schedule 17.04.2021


คำตอบ (2)


คุณสามารถเปลี่ยน ApplicationUserStore ของคุณได้ดังต่อไปนี้

public class ApplicationUserStore : UserStore<ApplicationUser,IdentityRole<int>, ApplicationDbContext,int>
{
    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }
    //...
}
person Yinqiu    schedule 15.04.2021
comment
ฉันยังได้ปรับแต่งบทบาท ดังนั้นคำแนะนำของคุณจึงใช้ได้กับการแก้ไขต่อไปนี้: public class ApplicationUserStore : UserStore‹ApplicationUser, ApplicationRole, ApplicationDbContext, int› อย่างไรก็ตาม ฉันได้รับข้อผิดพลาดต่อไปนี้เมื่อเรียก IsInRole : ไม่สามารถสร้าง DbSet สำหรับ 'IdentityUserRole‹int›' ได้ เนื่องจากประเภทนี้ไม่รวมอยู่ในโมเดลสำหรับบริบท} - person MaxTheCoder; 17.04.2021

แก้ไขแล้ว (ชั่วคราว)

หลังจากดูตัวเลือกการสืบทอดที่โอเวอร์โหลดแล้ว คุณต้องขยายดังนี้:

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, int, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationUserToken, ApplicationRoleClaim>
{
    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }
}

ดูเหมือนว่าจะได้ผล ยังคงต้องตรวจสอบบทบาททั้งหมดและอัปเดตการอ้างสิทธิ์

person MaxTheCoder    schedule 17.04.2021