在ASP.NET MVC站点中实现Session的可接受模式是什么?

时间:2010-03-05 23:19:35

标签: c# asp.net-mvc .net-3.5 session

显然,典型的WebForms方法不起作用。如何跟踪MVC世界中的用户?

2 个答案:

答案 0 :(得分:24)

Session的工作方式与Webforms的工作方式完全相同。如果要存储简单信息,请使用表单身份验证cookie。如果您想存储购物车的内容,可以选择Session。我写了一篇关于using Session with ASP.NET的博客文章:

让我们说我们想在Session中存储一个整数变量。我们将创建Session变量的包装器,使其看起来更好:

首先我们定义接口:

public interface ISessionWrapper
{
    int SomeInteger { get; set; }
}

然后我们进行HttpContext实现:

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); }
    }
}

GetFromSession和SetInSession是辅助方法,可以更轻松地在Session中获取和设置数据。 SomeInteger属性使用这些方法。

然后我们定义我们的基本控制器(适用于ASP.NET MVC):

public class BaseController : Controller
{
    public ISessionWrapper SessionWrapper { get; set; }

    public BaseController()
    {
        SessionWrapper = new HttpContextSessionWrapper();
    }
}

如果你想使用Session outside controller,你只需创建或注入新的HttpContextSessionWrapper()。

您可以在Controller测试中将SessionWrapper替换为ISessionWrapper mock,因此它不再依赖于HttpContext。 Session也更容易使用,因为您调用SessionWrapper.SomeInteger而不是调用(int)Session [“SomeInteger”]。它看起来更好,不是吗?

您可能会想到创建覆盖Session对象的静态类,并且不需要在BaseController中定义任何接口或初始化,但它会失去一些优点,特别是在测试和替换其他实现时。

答案 1 :(得分:2)

以下是我使用的代码,只是上述版本的一些“改进版”:

private T GetFromSessionStruct<T>(string key, T defaultValue = default(T)) where T : struct 
{
    object obj = HttpContext.Current.Session[key];
    if (obj == null)
    {
        return defaultValue;
    }
    return (T)obj;
}

private T GetFromSession<T>(string key) where T : class
{
    object obj = HttpContext.Current.Session[key];
    return (T)obj;
}

private T GetFromSessionOrDefault<T>(string key, T defaultValue = null) where T : class
{
    object obj = HttpContext.Current.Session[key];
    if (obj == null)
    {
        return defaultValue ?? default(T);
    }
    return (T)obj;
}

private void SetInSession<T>(string key, T value)
{
    if (value == null)
    {
        HttpContext.Current.Session.Remove(key);
    }
    else
    {
        HttpContext.Current.Session[key] = value;
    }
}