MVC tracking fields such as Author and Editor (Created By and Modified By)

送分小仙女□ 提交于 2019-12-11 05:07:09

问题


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; }
}

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);
    }
}

but this gives error because userManager.GetUserAsync(httpContext.User); requires an await and public override EntityEntry<TEntity> Add<TEntity>(TEntity entity) is not async.


回答1:


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.

I suggest you try get the current user by querying DbSet<ApplicationUser> with current user name.

Here is a simple code:

    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);            
    }        
}


来源:https://stackoverflow.com/questions/49142880/mvc-tracking-fields-such-as-author-and-editor-created-by-and-modified-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!