我想从IPrincipal获取当前用户的用户名,加载该用户的其他信息,并将其存储在会话中。然后我想从Controller和View访问该用户数据。
以下方法似乎都不符合我想要做的事情。
选项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
这个选项似乎相当不错,但我仍然不确定如何将它附加到Controller和View。我可以在控制器中新增,但不应该作为依赖注入?
- 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:使用Brad Wilson的StatefulStorage类
他的presentation年Brad Wilson拥有他的StatefulStorage类。它是一个聪明有用的类,包括接口和使用构造函数注入。但是,它似乎导致我与选项2相同的路径。它使用接口,但是我不能使用容器来注入它,因为它依赖于静态工厂。即使我可以注入它,它如何传递给视图。每个viewmodel都必须有一个可设置的User属性的基类?
选项4:使用类似于Hanselman IPrincipal ModelBinder的内容
我可以将User作为参数添加到Action方法中,并使用ModelBinder从Session中进行合并。这似乎是很多开销添加到它需要的地方。此外,我还是必须将其添加到viewmodel以使其可用于View。
- public ActionResult Edit(int id,[ModelBinder(typeof(IPrincipalModelBinder))] IPrincipal user)
- { ... }
我觉得我是在反思这个,但似乎应该有一个明显的地方去做这样的事情。我失踪了什么
解决方法
封面会话界面:
- public interface ISessionWrapper
- {
- int SomeInteger { get; set; }
- }
使用HttpContext.Current.Session实现接口:
- public class HttpContextSessionWrapper : ISessionWrapper
- {
- private T GetFromSession<T>(string key)
- {
- return (T) HttpContext.Current.Session[key];
- }
- private void SetInSession(string key,object value)
- {
- HttpContext.Current.Session[key] = value;
- }
- public int SomeInteger
- {
- get { return GetFromSession<int>("SomeInteger"); }
- set { SetInSession("SomeInteger",value); }
- }
- }
注入控制器:
- public class BaseController : Controller
- {
- public ISessionWrapper SessionWrapper { get; set; }
- public BaseController(ISessionWrapper sessionWrapper)
- {
- SessionWrapper = sessionWrapper;
- }
- }
Ninject依赖:
- Bind<ISessionWrapper>().To<HttpContextSessionWrapper>()
当您要在母版页中使用ViewData并在特定视图中使用视图模型时,可以使用ViewData传递一些常用信息。