ASP.NET Core 实体更改历史

Nic*_*ick 2 audit-logging entity-framework-core asp.net-core 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要实现实体编辑(审计)历史。

而且,由于该方法被标记为[Authorize],我需要记录它是由哪个用户编辑的。我正在看Audit.NET,但我没有找到方法来做到这一点。

the*_*000 5

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

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

在您的 asp net 启动代码上,设置一种获取当前信息的方法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;
                }));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是假设您的审计实体具有共同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;
        }));
Run Code Online (Sandbox Code Playgroud)