jed*_*atu 16 asp.net-mvc session-state asp.net-mvc-3
我在MVC中阅读了许多关于会话范围数据的帖子,但我仍然不清楚在解决方案中包含自定义会话包装器的正确位置.
我想从IPrincipal获取当前用户的用户名,加载有关该用户的其他信息并将其存储在Session中.然后我想从Controller和View访问该用户数据.
以下方法似乎都不符合我的要求.
选项1:直接访问Session集合
每个人似乎都认为这是一个坏主意,但老实说,这似乎是最简单的事情.但是,它不会使用户可用于视图.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
选项2:将会话注入到类构造函数 论坛帖子中
这个选项似乎很不错,但我仍然不确定如何将它附加到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
}
}
}
Run Code Online (Sandbox Code Playgroud)
选项3:使用Brad Wilson的StatefulStorage类
在他的演讲中, Brad Wilson展示了他的StatefulStorage课程.它是一组聪明且有用的类,包括接口和使用构造函数注入.但是,它似乎引导我沿着与选项2相同的路径.它使用接口,但我无法使用Container来注入它,因为它依赖于静态工厂.即使我可以注入它,它如何传递给View.每个ViewModel是否必须具有带有setable User属性的基类?
选项4:使用类似于Hanselman IPrincipal ModelBinder的东西
我可以将User作为参数添加到Action方法中,并使用ModelBinder从Session中对其进行水合.在任何需要的地方添加它似乎都需要很多开销.另外,我仍然需要将它添加到ViewModel以使其可用于View.
public ActionResult Edit(int id,
[ModelBinder(typeof(IPrincipalModelBinder))] IPrincipal user)
{ ... }
Run Code Online (Sandbox Code Playgroud)
我觉得我在想这个,但似乎应该有一个明显的地方去做这种事情.我错过了什么?
Luk*_*Led 13
我对Session的态度:
封面会话界面:
public interface ISessionWrapper
{
int SomeInteger { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用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); }
}
}
Run Code Online (Sandbox Code Playgroud)
注入控制器:
public class BaseController : Controller
{
public ISessionWrapper SessionWrapper { get; set; }
public BaseController(ISessionWrapper sessionWrapper)
{
SessionWrapper = sessionWrapper;
}
}
Run Code Online (Sandbox Code Playgroud)
Ninject依赖:
Bind<ISessionWrapper>().To<HttpContextSessionWrapper>()
Run Code Online (Sandbox Code Playgroud)
如果ViewData要在母版页中使用它并在特定视图中使用视图模型,可以使用一些常用信息.
| 归档时间: |
|
| 查看次数: |
5035 次 |
| 最近记录: |