我有一个包含两个项目的解决方案,我的API层和我的数据层。
数据层使用的是Entity Framework,并且不了解ASP.NET WebApi。
API层正在使用ASP.NET WebApi。
我计划使用Audit.NET审核记录更改。
当前,我已经在我的API项目中安装了Audit.NET,Audit.EntityFramework和Audit.WebApi。
我希望使用审核过滤器属性。 (config.Filters.Add(new AuditApiAttribute());
)
我的问题是,当我要填充EntityLog对象时,我也想用当前正在执行授权操作的用户的ID填充UserId字段;如果该操作是匿名的,则为null。
作为Startup.cs的一部分,我运行此功能来配置Audit.NET:
private void ConfigureAudit()
{
Audit.Core.Configuration.Setup()
.UseEntityFramework(x => x
.AuditTypeMapper(t => typeof(AuditLog))
.AuditEntityAction<AuditLog>((ev, entry, entity) =>
{
entity.UserId = ???;
// other fields...
})
.IgnoreMatchedProperties()
);
}
很明显,此时我不能使用HttpContext.Current.User.Identity.GetUserId()
,因为我不在控制器内部,而且我看不到将UserId传递给Audit事件的方法。
此时我如何检索UserId?
答案 0 :(得分:1)
一些用于ASP.NET Core的东西...
鉴于ASP.NET Core已删除HttpContext.Current
以支持基于DI的访问,我想在@ thepirat000的答案中添加一些更新,以反映访问{{1}的一种可能方式}在控制器外部。
在HttpContext
中的ConfigureServices
方法中,注册依赖项:
Startup.cs
在方法services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
中的Configure
中为注册的依赖项添加参数注入,使用它来获取上下文并使用它来设置自定义字段。
Startup.cs
照常访问自定义字段:
public void Configure(/* your existing parameters... */, IHttpContextAccessor httpContextAccessor)
{
...
Audit.Core.Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
{
scope.SetCustomField("User", httpContextAccessor.HttpContext.User.Identity.Name);
});
}
答案 1 :(得分:0)
我使用的方法是IUserContextLocator接口,该接口成为对DbContext或任何实现审核的类的依赖。该接口的实现在Web应用程序中创建,并通过依赖项注入进行连接,以使用构造函数初始化来提供当前会话的详细信息。这样DbContext或其他审核服务可以从IUserContextLocator中的方法解析当前用户结构,该方法又从会话中获取。
我当前的实现正在工作中,因此我没有一个方便的示例,但是明天我可以添加它的胆量。在这里可以看到类似的原理:http://josephwoodward.co.uk/2014/06/sessions-asp-net-mvc-using-dependency-injection/
本质上,域级代码无法访问HttpContext.Current之类的东西,但是在Web应用程序中初始化的实现可以。通过域可以引用的公共接口在您的DI中注册该实现,可以注入Web应用程序提供的依赖项,从而允许您访问会话数据。此示例将其称为注册表,这可能是一种更准确的模式。
答案 2 :(得分:0)
除了史蒂夫(Steve)的答案,我想您应该还可以从Custom Field中添加一个OnScopeCreated custom action,就像在asp.net启动逻辑上一样:
Audit.Core.Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
{
scope.SetCustomField("User", HttpContext.Current.User.Identity.GetUserId());
});
因此,您将在EF数据提供者的AuditEvent上具有该字段,并且应该能够像这样进行检索:
Audit.Core.Configuration.Setup()
.UseEntityFramework(_ => _
.AuditTypeMapper(t => typeof(AuditLog))
.AuditEntityAction<AuditLog>((ev, entry, entity) =>
{
var x = ev.CustomFields["User"];
...
})
.IgnoreMatchedProperties());
注意:如果您仅对审核实体框架数据库上下文感兴趣,则不需要
Audit.WebApi
库。那是为了审计控制器的动作。