背景
我有一个Web应用程序,我需要为插入/删除/更新(也许是读取)进行数据库审计。我使用LINQ作为我的ORM。使用我在网络上找到的一些想法,我想出了一种使用属性来装饰我的实体的方法,这些实体具有相关的审计表。除了当前用户的id和名称的字段,修改类型,修改时间以及操作是否成功之外,审计表本身还需要包含与原始表具有相同类型的相同列。审计发生在SubmitChanges期间 - 我的数据上下文是抽象的,我在具体实现中继承并覆盖SubmitChanges。抽象数据上下文实际上派生自一个AbstractAuditableDataContext,它扩展了DataContext并为当前用户ID和名称添加了一个带有占位符的CurrentUser属性。默认情况下,对于没有登录用户的实例,这些是0和“system” - 例如在注册或登录期间可能更新用户表的某些字段。该应用程序是使用ASP.NET MVC用C#编写的。
问题:
填充派生数据上下文的当前用户属性的最佳方法是什么?我应该创建一个在AuditUtility中注入的实用程序类,它检查是否已经设置了CurrentUser,如果没有,则填充它。对于测试我会嘲笑它,但在实时应用程序中它可能会使用lazy在会话中加载并获取/设置它。或者我应该修改数据上下文工厂(由所有控制器使用)来执行此功能。我已经在单元测试期间使用了模拟工厂,因此这不会涉及创建新类。或者,推导是在工厂外完成的,当前用户是在创建上下文期间注入的。这将允许我“代表”审计。
我意识到这有点主观,但我很感激您可能贡献的任何想法/经验。
感谢。
答案 0 :(得分:1)
如果您正在使用Windows或Forms身份验证,则可以检查HttpContext而不传入任何内容。如果您不在Web上下文中,请从线程中获取用户。也许:
if(HttpContext.Current != null)
{
//grab the user from the HttpContext
}
else
{
//grab the user from the Thread
}
答案 1 :(得分:1)
System.Threading.Thread.CurrentPrincipal
应该为您提供所需的答案。
答案 2 :(得分:0)
DataContext的范围是什么(应用程序,会话,请求,每个BusinessObject ..)?如果它有所不同,您可能根本不想在DataContext中缓存当前用户(或在创建期间设置它)。我可能会在DataContext中使用一个Property,它在需要时从Session(以某种方式)检索当前用户。
答案 3 :(得分:0)
我最终创建了一个CurrentUserUtilityBase类,该类具有GetAuditUser方法,该方法获取当前数据上下文并检索与HttpContext.User.Identity中当前用户名对应的用户对象。它使用此对象提取当前用户的id和显示名称,并创建并返回包含这些属性的AuditUser对象。
我的实现类使用工厂来获取我的数据上下文的实例,并在此数据上下文中调用基类方法。我的数据上下文的工厂方法使用当前用户实用程序在创建后将上下文的当前用户注入上下文。