Добавление коллекции в пользовательский объект в ASP.NET Core с удостоверением - PullRequest
0 голосов
/ 25 сентября 2018

Я поигрался с EF Core и ASP.NET Core и наткнулся на следующую проблему.Я хотел добавить некоторые дополнительные данные в пользовательский объект в виде списка.Проблема в том, что список никогда не обновляется.

Вот мой DbContext:

public class ApplicationDbContext : IdentityDbContext<HostUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }
}

А теперь мой пользовательский объект:

public class HostUser : IdentityUser
{
    [PersonalData]
    public ICollection<GuestUser> GuestUsers { get; set; }
}

А вот добавлениеновый GuestUser в Contoller:

[HttpPost]
    public async Task<IActionResult> Post([FromBody]GuestUser userToInsert)
    {
        if (userToInsert == null)
        {
            return BadRequest();
        }

        var currentUser = await GetCurrentUserAsync();
        if (currentUser == null)
        {
            return Forbid();
        }

        if(currentUser.GuestUsers?.Any(user => user.Id == userToInsert.Id) ?? false)
        {
            return BadRequest();
        }

        if(currentUser.GuestUsers == null)
        {
            currentUser.GuestUsers = new List<GuestUser>();
        }

        currentUser.GuestUsers.Add(userToInsert);
        await userManager.UpdateAsync(currentUser);

        return Ok();
    }

Мой вопрос заключается в том, является ли это совершенно неправильным подходом, и мне нужно добавить DbSet для GuestUser в DbContext и сопоставить его с пользователем.Если это так, я понятия не имею, как этого добиться.Примечание. В этом случае GuestUser - это не другой IdentityUser, это данные локального пользователя

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Вот как это может выглядеть:

Право:

public class HostUser : IdentityUser
{
    public virtual ICollection<GuestUser> GuestUsers { get; set; }
}

public class GuestUser
{
    public int HostUserId { get; set; }
    public virtual HostUser HostUser { get; set; }
}

Контекст БД:

public class ApplicationDbContext : IdentityDbContext<HostUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<GuestUser> GuestUsers { get; set; }

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

        builder.Entity<HostUser>(
            typeBuilder =>
            {
                typeBuilder.HasMany(host => host.GuestUsers)
                    .WithOne(guest => guest.HostUser)
                    .HasForeignKey(guest => guest.HostUserId)
                    .IsRequired();

                // ... other configuration is needed
            });

        builder.Entity<GuestUser>(
            typeBuilder =>
            {
                typeBuilder.HasOne(guest => guest.HostUser)
                    .WithMany(host => host.GuestUsers)
                    .HasForeignKey(guest => guest.HostUserId)
                    .IsRequired();

                // ... other configuration is needed
            });
    }
}

Действие контроллера:

[HttpPost]
public async Task<IActionResult> Post([FromBody] GuestUser userToInsert)
{
    // All checks and validation ...

    // You can get the current user ID from the user claim for instance
    int currentUserId = int.Parse(User.FindFirst(Claims.UserId).Value);

    // _context is your ApplicationDbContext injected via controller constructor DI 
    userToInsert.HostUserId = currentUserId;

    // Save new guest user associated with the current host user
    _context.GuestUsers.Add(userToInsert);
    await _context.SaveChangesAsync();

    // If you need to get the current user with all guests
    List<HostUser> currentUser = await _context.Users.Include(host => host.GuestUsers).ToListAsync();

    return Ok(currentUser);
}

Здесь я предоставил полный код - , как настроить пользовательский контекст БД на основе идентификаторов (все необходимые пользовательские классы наследуются от базовых классов, используемых IdentityDbContext).

0 голосов
/ 25 сентября 2018

Существует две проблемы.

1. Сначала вы должны отделить ViewModel от сущности (не передавайте GuestUser в качестве метода web / api для параметра)

2.затем, как вы упомянули, вы должны объявить DBSet из GuestUser в DbContext и сопоставить его с таблицей пользователей.

Определить свою пользовательскую сущность пользователя

public class ApplicationUser : IdentityUser
{
    public string CustomTag { get; set; }
}

Объявите свой пользовательский DbContext

Далее используйте этот тип в качестве универсального аргумента для контекста:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

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

        modelBuilder.Entity<ApplicationUser>(b =>
        {
            // Each User can have many UserClaims
            b.HasMany(e => e.Claims)
                .WithOne()
                .HasForeignKey(uc => uc.UserId)
                .IsRequired();
        });
    }
}

Обновите ConfigureServices для использования нового класса ApplicationUser:

services.AddDefaultIdentity<ApplicationUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

, если у вас есть какие-либо другие проблемы, сообщите мне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...