在我目前从事的项目中,我需要审核对许多数据库表的更改。为此,我正在考虑使用nuget Z.EntityFramework.Plus.Audit.EFCore 。我一直在尝试,它似乎基本上可以满足我的需求。我一直在关注文档here。
可以将审核条目保存在我的控制器中,如下所示:
public myFunction(){
//...
var audit = new Audit();
_context.SaveChanges(audit);
}
但是,如果我以这种方式这样做,那将违反DRY原则。有一种方法可以覆盖SaveChanges()和SaveChagesAsync()函数,并且可以解决问题。这样的事情是这样完成的:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
// ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
(context as ApplicationDbContext).AuditEntries.AddRange(audit.Entries);
}
public override int SaveChanges()
{
var audit = new Audit { }; //Problem would be here
audit.PreSaveChanges(this);
var rowAffecteds = base.SaveChanges();
audit.PostSaveChanges();
if (audit.Configuration.AutoSavePreAction != null)
{
audit.Configuration.AutoSavePreAction(this, audit);
base.SaveChanges();
}
return rowAffecteds;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
var audit = new Audit { }; //Problem would be here
audit.PreSaveChanges(this);
var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
audit.PostSaveChanges();
if (audit.Configuration.AutoSavePreAction != null)
{
audit.Configuration.AutoSavePreAction(this, audit);
await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
return rowAffecteds;
}
//... DbContext Code
}
现在,这是一种更好的选择,非常干燥且易于维护。问题是,如何获取当前的用户名,以便我可以做类似
的操作var audit = new Audit { CreatedBy = "my_current_username"};
在控制器中,您可以使用指令
var username = this.User.Identity.Name;
,但是在IdentityDbContext中不可用。我确实尝试注入UserManager,但是它没有可能起作用的功能。
tl; dr; 当我使用JWT令牌时如何在IdentityDbContext中获取当前的用户名?
答案 0 :(得分:2)
在ConfigureServices
中:
services.AddHttpContextAccessor();
services.AddDbContext<FooContext>((provider, options) =>
options.UseSqlServer(Configuration.GetConnectionString("Foo"))
.UseInternalServiceProvider(provider);
在FooContext.SaveChanges
/ FooContext.SaveChangesAsync
中:
var httpContextAccessor = this.GetService<IHttpContextAccesor>();
var userName = httpContextAccessor.HttpContext?.User.Identity.Name;
if (userName != null)
{
// You've got the username. Do something with it.
}
答案 1 :(得分:-1)
您可以注入IHTTPContextAccessor服务,然后使用该服务获取当前的用户名。但是,此服务不是线程安全的 另外,这意味着您不能再在Web应用程序AFAIK范围之外使用DBContext。
此处有更多信息:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2