【问题标题】:ASP.NET Core Entity changing historyASP.NET Core 实体更改历史
【发布时间】:2018-09-22 18:20:45
【问题描述】:

我有很多这样的控制器:

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,但我没有找到方法。

【问题讨论】:

  • 一种方法是在 OnActionExecuting 或 OnActionExecuted 中使用操作过滤器。 gist.github.com/mgroves/1832983 之类的内容应该可以帮助您入门。
  • 但是如何保存(旧值、新值、用户名)?它只是一个触发器
  • 您从上下文中获取用户名,即context.HttpContext.User.Identity.Name 和来自context.ActionArguments 的参数。假设您在模型中有 PK,您可以查找旧值。
  • 我没试过,但也许可以试试Entity Framework Plus的audit组件,它有一些很好的examples

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


【解决方案1】:

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&lt;T&gt;

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

【讨论】:

    【解决方案2】:

    在 IOC 中获取 UserID:

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-16
      • 1970-01-01
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 2014-12-08
      相关资源
      最近更新 更多