【问题标题】:Updating common field with user email使用用户电子邮件更新公共字段
【发布时间】:2018-06-07 02:27:03
【问题描述】:

我正在尝试找出授权用户当前正在尝试保存数据并记录他们的电子邮件。

我的 dbcontext 中有一个基本设置,用于更新时间戳,但我不知道如何访问用户信息:

    public override int SaveChanges()
{
    AddTimestamps();
    return base.SaveChanges();
}


public override async Task<int> SaveChangesAsync()
        {
            AddTimestamps();
            return await base.SaveChangesAsync();
        }

    private void AddTimestamps()
    {
        var entities = ChangeTracker.Entries()
            .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);

        var currentUser = "dumm@dummy.com" // This i haven't been able to figure out how to retrieve

        foreach (var entity in entities)
        {
            if (entity.State == EntityState.Added)
            {
                ((BaseEntity)entity.Entity).DateCreated = DateTime.UtcNow;
                ((BaseEntity)entity.Entity).CreatedBy = currentUsername;
            }

            ((BaseEntity)entity.Entity).DateModified = DateTime.UtcNow;
            ((BaseEntity)entity.Entity).ModifiedBy = currentUsername;
        }
    }
}

更多的背景知识,这一切都建立在 ASP Core 2 和 EF Core 之上。 DBContext 位于我的 APIContoso 项目中,该项目使用名为 IDPContoso 的自定义身份提供程序,该身份提供程序基于 ASP Core 2 和 Identity Server4 构建。

如何在 DBContext 中获取用户的电子邮件以便记录?

【问题讨论】:

  • 你实现了DbContext 是从IdentityDbContext 派生的还是你想在SavaChange 时实现自定义身份验证。
  • ChangeTracker.Entries 允许您获取特定类型的所有附加条目,而不是强制转换它们并可能遇到空引用。

标签: asp.net entity-framework entity-framework-core identityserver4 asp.net-core-2.0


【解决方案1】:

我建议您从身份获取电子邮件。这样您就不需要额外调用数据库。如果您使用电子邮件登录,则 User.Identity.Name 包含电子邮件(如果映射正确)。否则添加包含电子邮件的声明。

现在您需要将电子邮件注入模型。我假设模型有一个单独的项目。在这种情况下,您不能只注入 IHttpContextAccessor。否则,您可以在构建模型时简单地注入 IHttpContextAccessor 并读取用户信息。

以下代码仅用于演示目的。在 Startup.cs 中注入一个包含 connectionInfo 的对象:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped(provider => new Database.ConnectionInfo
    {
        ConnectionString = provider.GetRequiredService<ApplicationSettings>().ConnectionString,
        User = provider.GetRequiredService<IHttpContextAccessor>().HttpContext.User?.Identity.Name
    });
    services.AddScoped<Model>();
}

因为这是有范围的,所以每次用户连接时,都会设置用户信息。对于匿名用户,User = null。请注意,模型本身也有作用域。 connectionInfo 类:

public class ConnectionInfo
{
    public string ConnectionString { get; set; }
    public string User { get; set; }
}

现在在模型中你有以下构造函数:

private string _user { get; }

public Model(ConnectionInfo connection)
    : base(connection.ConnectionString)
{
    _user = connection.User;
}


private void AddTimestamps()
{
    var entities = ChangeTracker.Entries()
        .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified);

    var currentUser = _user;
}

【讨论】:

    猜你喜欢
    • 2012-05-07
    • 2017-12-29
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多