Asp.net mvc 将用户名注入dbContext(实体框架6)以自动更新列ModifiedBy/CreatedBy
我正在建立一个MVC5、WebApi 2、实体框架解决方案。我希望在数据库中插入审计字段,而不必每次都编写样板代码。我的数据库实体位于它们自己的独立项目中,该项目引用EntityFramework 到目前为止,我已经:Asp.net mvc 将用户名注入dbContext(实体框架6)以自动更新列ModifiedBy/CreatedBy,asp.net-mvc,entity-framework,asp.net-web-api,asp.net-identity,autofac,Asp.net Mvc,Entity Framework,Asp.net Web Api,Asp.net Identity,Autofac,我正在建立一个MVC5、WebApi 2、实体框架解决方案。我希望在数据库中插入审计字段,而不必每次都编写样板代码。我的数据库实体位于它们自己的独立项目中,该项目引用EntityFramework 到目前为止,我已经: public class MyDbContext : IdentityDbContext<ApplicationUser> { public MyDbContext(/*Autofac can inject stuff here*/)
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
public MyDbContext(/*Autofac can inject stuff here*/)
{
}
public override int SaveChanges()
{
// Updates ModifiedBy, CreatedBy, ModifiedOn, CreatedOn fields
DbContextHelper.TrackSaveChanges(ChangeTracker, userName);
return base.SaveChanges();
}
}
公共类MyDbContext:IdentityDbContext
{
公共MyDbContext(/*Autofac可以在此处注入内容*/)
{
}
公共覆盖int SaveChanges()
{
//更新ModifiedBy、CreatedBy、ModifiedOn、CreatedOn字段
TrackSaveChanges(ChangeTracker,用户名);
返回base.SaveChanges();
}
}
TrackSaveChanges()
中的逻辑并不重要,它只是在所有更改的实体上循环,并在字段上设置值。没什么太聪明的
问题是在我的DbContext
派生类中获取userName
。我认为最好的方法是将其注入到MyDbContext
构造函数中
有人建议使用HttpContext.Current.User
,但我不希望在数据项目中添加Web依赖项。直接引用HttpContext
也会损害单元的可测试性
- 我在Autofac
将builder.Register(ip=>HttpContext.Current.User)中尝试过
注入dbcontext,但这会引发异常,因为HttpContext.Current.User在创建时为null李>IPrincipal
- 如果必须的话,我更愿意使用
代替HttpContextBase
HttpContext
我使用的是实体框架6、WebAPI 2、ASP NET Identity和Autofac 您可以插入一个接口,而不是
字符串
值本身:
interface IUserNameProvider
{
string GetUserName();
}
具体的实现将使用HttpContext.Current.User
,但这种方法不会损害可测试性,因为接口很容易被模拟
interface HttpContextUserNameProvider : IUserNameProvider
{
public string GetUserName()
{
return HttpContext.Current.User;
}
}
客户端代码示例:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
internal IUserNameProvider _userNameProvider;
public MyDbContext(IUserNameProvider userNameProvider)
{
_userNameProvider = userNameProvider;
}
public override int SaveChanges()
{
string userName = _userNameProvider.GetUserName();
// ...
}
}
公共类MyDbContext:IdentityDbContext
{
内部IUserNameProvider\u userNameProvider;
公共MyDbContext(IUserNameProvider userNameProvider)
{
_userNameProvider=userNameProvider;
}
公共覆盖int SaveChanges()
{
字符串用户名=_userNameProvider.GetUserName();
// ...
}
}
是的,我现在也在想同样的事情,尽管我希望我可以使用现有的IPrincipal逃脱。您还知道从HttpContextBase获取用户名的方法吗?