MVC跟踪字段,例如作者和编辑者(创建者和修改者) [英] MVC tracking fields such as Author and Editor (Created By and Modified By)
问题描述
我正在寻找跟踪数据库中所有实体的作者"和编辑者"字段的最佳方法.
I'm looking for the best way to track the Author and Editor fields for all the entities in my database.
我首先创建了一个基础模型,我的所有模型都继承自该模型:
I started by creating a base model which all my models inherit from:
public class DatabaseEntity
{
[Key]
public int Id { get; set; }
[Display(Name = "Last Modified By")]
public ApplicationUser Editor { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
[Display(Name = "Last Modified")]
public DateTime LastModified { get; set; }
[Display(Name = "Created By")]
public ApplicationUser Creator { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime Created { get; set; }
}
这很好,但是我必须在控制器的每个动作中设置这些字段.每次更新或编辑数据库中的项目时,如何设置这些字段?我知道我可以覆盖DbContext
中的Add
,但是我不知道如何从DbContext
中的HttpContext.Current.User.Identity
获取ApplicationUser
.我已经尝试过:
This works good, but I have to set these fields in every action in my controllers. How can I set these fields every time an item in my database is updated or edited? I am aware that I could override Add
in my DbContext
, but I have no idea how to get the ApplicationUser
from the HttpContext.Current.User.Identity
in my DbContext
. I have tried:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {
private readonly UserManager<ApplicationUser> userManager;
private readonly HttpContext httpContext;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor)
: base(options)
{
this.contextAccessor = contextAccessor;
this.httpContext = contextAccessor.HttpContext;
this.userManager = userManager;
}
public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
{
DatabaseEntity dbEntity = (entity as DatabaseEntity);
if (dbEntity != null)
{
dbEntity.Created = DateTime.Now;
dbEntity.Creator = await userManager.GetUserAsync(httpContext.User);
}
return base.Add(entity);
}
}
但这会产生错误,因为userManager.GetUserAsync(httpContext.User);
需要await
并且public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
不是异步的.
but this gives error because userManager.GetUserAsync(httpContext.User);
requires an await
and public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
is not async.
推荐答案
要获取当前用户,请勿使用UserManager<ApplicationUser>
.在注释dbEntity.Creator = await userManager.GetUserAsync(httpContext.User);
时,您将得到错误检测到类型为'CoreDb.Data.ApplicationDbContext'的服务的循环依赖性.,因为您访问了ApplicationDbContext
中的UserManager<ApplicationUser>
.
For getting current user, you should not use UserManager<ApplicationUser>
. With commenting dbEntity.Creator = await userManager.GetUserAsync(httpContext.User);
, you will get error A circular dependency was detected for the service of type 'CoreDb.Data.ApplicationDbContext'. due to that you accessing UserManager<ApplicationUser>
in ApplicationDbContext
.
我建议您尝试通过使用当前用户名查询DbSet<ApplicationUser>
来获取当前用户.
I suggest you try get the current user by querying DbSet<ApplicationUser>
with current user name.
这是一个简单的代码:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly HttpContext httpContext;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor contextAccessor)
: base(options)
{
this.httpContext = contextAccessor.HttpContext;
}
public DbSet<ApplicationUser> ApplicationUser { get; set; }
public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
{
DatabaseEntity dbEntity = (entity as DatabaseEntity);
var userName = httpContext.User.Identity.Name;
if (dbEntity != null)
{
dbEntity.Created = DateTime.Now;
dbEntity.Creator = userName == null ? null : ApplicationUser.Where(user => user.UserName == userName).FirstOrDefault();
}
return base.Add(entity);
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
这篇关于MVC跟踪字段,例如作者和编辑者(创建者和修改者)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!