从数据层访问 HttpContext 和用户身份



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

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

从数据层访问 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 layer
public class MyDaoService {
    public DaoService(ICurrentUserService currentUser) { ... }
}

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

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

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

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 内容。

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

我使用工厂来获取带有或不带有"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 中提取标识,并仅将所需的详细信息传递给存储库。

  1. HttpContext.User.Identity属于System.Security.Principal.IIdentity类型。不要用Microsoft.AspNet.Identity库(NuGet包)搞砸它,它实际上是由问题中的 asp.net 标识标记指向的。

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

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

相关内容

  • 没有找到相关文章

最新更新