我有很多像这样的控制器:
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
,但我找不到办法。
答案 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