从数据层访问HttpContext和用户标识

时间:2015-04-17 20:06:09

标签: c# asp.net-mvc asp.net-identity httpcontext

我需要在我的基本实体上实现AddedBy / ChangedBy类型字段,所有其他实体都继承自(Fluent Nhibernate)。

从我的存储库/数据层访问HttpContext.User.Identity可能不是一个好主意......或者是它? 获取用户(当前身份)信息以记录添加或更改记录的人的最佳方法是什么? 重新分解整个应用程序以在存储库调用中包含用户信息将是愚蠢的。我确信有一种更好,更通用的方式。

6 个答案:

答案 0 :(得分:9)

访问DataLayer中的HttpContext会使生活更加艰难,特别是如果您使用单元测试。解决方案是提供服务以提供应用程序范围的用户信息,例如:

public interface ICurrentUserService {
   string UserName {get;}
   string UserId {get;}
   string HostIP {get;}
   // etc.
}

然后你可以实现具体的服务并注入使用你的 首选的IoC容器。

public class CurrentWebUserService : ICurrentUserService {
    // implement interface members 
    public CurrentWebUserService(HttpContext context) { ... }

    public string UserName { get { ... } } 
    // etc.
}

// maybe you want a stub service to inject while unit testing.
public class CurrentUserServiceStub : ICurrentUserService {

}

// data 
public class MyDaoService {
    public DaoService(ICurrentUserService currentUser) { ... }
}

答案 1 :(得分:1)

你是对的。从存储库中引用您的HttpContext.User.Identity类不是一个好主意。 HttpContext是一个UI问题,因此,应该只是UI层。

您应该做的是利用IoC容器(例如StructureMap)将依赖项(HttpContext.User.Identity)详细信息注入您的存储库,或通过依赖注入将任何其他层(如服务层)注入。

有关如何设置它的示例(在本例中它是会话对象),请参阅this answer的后半部分。

答案 2 :(得分:0)

AddedBy / ChangedBy字段在任何数据后端都可能很重要。您甚至可能希望将AccessedBy用于记录目的。因此,您可能希望认为用户信息是数据的核心部分。出于安全原因,您可能还需要记录其他详细信息,例如客户端的IP地址。将整个上下文波及到数据层可能是一个好主意,这样您就可以灵活地捕获和保存客户端信息。

答案 3 :(得分:0)

HttpContext.Current是一个静态成员,您可以在应用程序的任何位置访问它。 https://msdn.microsoft.com/en-us/library/system.web.httpcontext.current%28v=vs.110%29.aspx 显然存在问题,例如,如果在调用代码时没有HttpContext。

所以HttpContext.Current.User应该适合你。我不推荐它,因为您的基础数据访问代码现在依赖于应该保留给您的显示器或控制器逻辑等的东西。此外,这假设您的数据访问是在Web应用程序本身而不是,比如,一个外部图书馆。

就个人而言,我只是将重要的细节(如用户ID和访问时间)作为添加和修改数据库调用的一部分传递。制作“AuditTrail”课程或其他内容。这样你就可以在另一个项目中重用那些数据访问代码(总是一件好事),而不必拔掉所有的HttpContext东西。

答案 4 :(得分:0)

我使用工厂来获得正确的回购,无论是否有" CurrentUser"因为有时你需要知道用户是谁,有时你不知道。

//I have a current user that I got from the Identity
var repo = RepoFactory.GetRepo<Users>(currentUserId);

//I don't have a current user
var repo = RepoFactory.GetRepo<Users>()

通过这种方式,您可以从HttpContext中提取Identity,并仅将您需要的详细信息传递给repo。

答案 5 :(得分:0)

  1. HttpContext.User.Identity属于System.Security.Principal.IIdentity类型。不要搞乱 Microsoft.AspNet.Identity 库(NuGet包),它在你的问题中实际上是由asp.net-identity标签指出的。

  2. Identity lib由公共部分及其ORM实现组成。通常是实体框架。但是,如果您按照NHibernate描述的方式使用Microsoft.AspNet.Identity包,那么您很可能需要this package

  3. 我没有使用它,但我使用了EF实现。请参阅this answer如何继承预定义的IdentityDbContext<T>,其中T是您的User类。我想,NH有类似的流畅配置。然后,您可以将DbContext中的任何实体与AppUser

    相关联