MVC跟踪字段,例如作者和编辑者(创建者和修改者) [英] MVC tracking fields such as Author and Editor (Created By and Modified By)

查看:88
本文介绍了MVC跟踪字段,例如作者和编辑者(创建者和修改者)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找跟踪数据库中所有实体的作者"和编辑者"字段的最佳方法.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆