Web API – 在DbContext类中访问HttpContext

在我的C#Web API应用程序中,我在所有表中添加了CreatedDateCreatedBy列。 现在,我想在任何表中添加新记录时填充这些列。

为此,我在DbContext类中重写了SaveChangesSaveChangesAsync函数,如下所示:

 public class AuthDbContext : IdentityDbContext { public override int SaveChanges() { AddTimestamps(); return base.SaveChanges(); } public override async Task SaveChangesAsync() { AddTimestamps(); return await base.SaveChangesAsync(); } private void AddTimestamps() { var entities = ChangeTracker.Entries().Where(x => (x.State == EntityState.Added)); var currentUsername = !string.IsNullOrEmpty(HttpContext.Current?.User?.Identity?.Name) ? HttpContext.Current.User.Identity.Name : "SYSTEM"; foreach (var entity in entities) { foreach (var propName in entity.CurrentValues.PropertyNames) { if (propName == "CreatedBy" && entity.State == EntityState.Added) { entity.CurrentValues[propName] = currentUsername; } else if (propName == "CreatedDate" && entity.State == EntityState.Added) { entity.CurrentValues[propName] = DateTime.Now; } } } } } 

现在,当我从控制器的任何地方调用SaveChangesSaveChangesAsync ,会分配HttpContext.Current ,我可以使用ttpContext.Current.User.Identity.Name从中获取用户名。 但是当我使用UserManager.UpdateAsync函数(在我们的DbContext类中内部调用SaveChangesAsync函数)来更改底层用户表时, HttpContext.Current被设置为null。

如何在此特定情况下访问HttpContext以获取用户名?

问题是,使用SaveChangesAsync您不知道是否可以访问HttpContext.Current因为您可能没有在请求被提供的线程上执行。

解决这个问题的最佳方法是使用DI。 您可以创建一个接口和匹配类,其中实现依赖于HttpContextBase 。 配置DI框架以将IUserContext实例注入DbContext并为每个请求创建UserContext的新实例。

至于使用哪个DI框架我偏爱Autofac,但有很多可供选择,并且大多数具有类似的function。

 public interface IUserContext { bool IsAuthenticated {get;} // additional properties like user id / name / etc } public class UserContext : IUserContext { public UserContext(HttpContextBase httpContext) { this.IsAuthenticated = httpContext.User.Identity.IsAuthenticated; // any other properties that you want to use later } }