我已经阅读了许多关于MVC中会话范围数据的文章,但我仍然不清楚在哪里可以将自定义会话包装器包含到解决方案中。
我想从IPrincipal中获取当前用户的用户名,加载有关该用户的附加信息,并将其存储在会话中。然后,我想从、控制器和视图访问该用户数据。
以下方法似乎都不适合我想要做的事情。
选项1:直接访问会话集合
似乎每个人都同意this is a bad idea,但老实说,它似乎是最简单的工作方式。但是,它不会使用户对视图可用。
public class ControllerBase : Controller {
public ControllerBase() : this(new UserRepository()) {}
public ControllerBase(IUserRepository userRepository) {
_userRepository = userRepository;
}
protected IUserRepository _userRepository = null;
protected const string _userSessionKey = "ControllerBase_UserSessionKey";
protected User {
get {
var user = HttpContext.Current.Session[_userSessionKey] as User;
if (user == null) {
var principal = this.HttpContext.User;
if (principal != null) {
user = _userRepository.LoadByName(principal.Identity.Name);
HttpContext.Current.Session[_userSessionKey] = user;
}
}
return user;
}
}
}
选项2:将会话注入类构造函数 forum post
这个选项似乎很好,但我仍然不确定如何将其附加到控制器和视图。我可以在控制器中新建它,但它不应该作为依赖项被注入吗?
public class UserContext {
public UserContext()
: this(new HttpSessionStateWrapper(HttpContext.Current.Session),
new UserRepository()) { }
public UserContext(HttpSessionStateBase sessionWrapper, IUserRepository userRepository) {
Session = sessionWrapper;
UserRepository = userRepository;
}
private HttpSessionStateBase Session { get; set; }
private IUserRepository UserRepository{ get; set; }
public User Current {
get {
//see same code as option one
}
}
}
选项3:使用布拉德·威尔逊的StatefulStorage类
布拉德·威尔逊在他的presentation中介绍了他的StatefulStorage课程。它是一组聪明而有用的类,其中包括接口并使用构造函数注入。然而,它似乎将我引向与选项2相同的道路。它使用接口,但我不能使用Container来注入它,因为它依赖于静态工厂。即使我可以注入它,它是如何传递到视图的。是否每个用户都必须有一个具有可设置ViewModel属性的基类?
选项4:使用与 类似的方法
我可以将用户作为参数添加到操作方法中,并使用ModelBinder从会话中对其进行消减。在需要的地方添加它似乎有很大的开销。另外,我仍然需要将其添加到ViewModel中,才能使其对视图可用。
public ActionResult Edit(int id,
[ModelBinder(typeof(IPrincipalModelBinder))] IPrincipal user)
{ ... }
我觉得我想得太多了,但似乎也应该有一个明显的地方来做这类事情。我遗漏了什么?
https://stackoverflow.com/questions/5060804
复制相似问题