ASP.NET核心实体更改历史记录

时间:2018-04-12 14:30:57

标签: asp.net-core entity-framework-core audit-logging audit.net

我有很多像这样的控制器:

public class EntityController : Controller
{
    private readonly IEntityRepository _entity;

    public EntityController(IEntityRepository entity)
    {
        _entity = entity;
    }

    [Authorize]
    [HttpPut("{id}")]
    public async ValueTask<IActionResult> Put(int id, [FromBody] Entity entity)
    {
        if (entity == null || entity.Id != id) return BadRequest();
        var updated = await _entity.Update(entity);
        if (updated == null) return NotFound();
        return Ok(updated);
    }

我需要实现实体编辑(审核)历史记录。

并且,由于该方法被标记为[Authorize],我需要记录它被编辑的用户。 我在看Audit.NET,但我找不到办法。

2 个答案:

答案 0 :(得分:3)

Audit.NET EF Provider允许在保存之前自定义审计实体。这必须在启动时使用所谓的AuditEntity Action来完成:为每个被修改的实体触发一个动作。

因此,您可以使此操作从当前HttpContext中检索用户名,并将其存储在审核实体的UserName属性中。

在您的asp网络启动代码上,设置获取当前HttpContext的方法并配置操作以从上下文中检索用户名:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add the HttpContextAccessor if needed.
        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        // Get the service provider to access the http context
        var svcProvider = services.BuildServiceProvider();

        // Configure Audit.NET
        Audit.Core.Configuration.Setup()
            .UseEntityFramework(x => x
                .AuditTypeNameMapper(typeName => "Audit_" + typeName)
                .AuditEntityAction((evt, ent, auditEntity) =>
                {
                    // Get the current HttpContext 
                    var httpContext = svcProvider.GetService<IHttpContextAccessor>().HttpContext;
                    // Store the identity name on the "UserName" property of the audit entity
                    ((dynamic)auditEntity).UserName = httpContext.User?.Identity.Name;
                }));
    }
}

这假设您的审计实体具有共同的UserName属性。

如果您的审核实体已经从包含UserName的接口或基类继承,则可以改为使用通用AuditEntityAction<T>

Audit.Core.Configuration.Setup()
    .UseEntityFramework(x => x
        .AuditTypeNameMapper(typeName => "Audit_" + typeName)
        .AuditEntityAction<IUserName>((evt, ent, auditEntity) =>
        {
            var httpContext = svcProvider.GetService<IHttpContextAccessor>().HttpContext;
            auditEntity.UserName = httpContext.User?.Identity.Name;
        }));

答案 1 :(得分:0)

要在IOC中获取用户ID:

var userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value 

how-get-current-user-in-asp-net-core