ASP.NET MVC会话与全局与缓存

时间:2009-05-27 12:32:42

标签: asp.net-mvc caching session-state

我有一个用vanilla ASP.NET编写的应用程序,我希望将其移植到ASP.NET MVC。

然而,我对于持久存在物体的正确位置感到困惑。我需要坚持几个原因:

  1. 我希望所有人都有一个单个数据库连接,包含在“存储库”或“经理”样式对象中。
  2. 每个用户都有一个需要按会话保存的用户对象。
  3. 通常情况下,我会说#1会被保存为Globals.asax中的静态项目,可以使用Global.Repository或类似命中。

    我通常会说#2应该是一个属性,在页面的基类中有一个会话支持存储。

    现在我感到困惑的原因是我听说MVC中的会话已经改变,并且Global.asax不再拥有相同的类。此外,页面的概念已被删除,因此向控制器的基类添加属性似乎......错误。

    你说什么?

4 个答案:

答案 0 :(得分:10)

您的数据库将进入控制器的基类。此基类应扩展Controller,并且所有控制器都应扩展基类。这是一个小例子:

public class BaseController : Controller
{
    private AuthServices _auth;
    private LogHelper _log;
    private Repository _repository;

    /// <summary>
    /// <see cref="AuthServices"/>
    /// </summary>
    protected AuthServices Authorization
    {
        get { return _auth ?? (_auth = new AuthServices()); }
    }

    /// <summary>
    /// <see cref="LogHelper"/>
    /// </summary>
    protected LogHelper Log
    {
        get { return _log ?? (_log = new LogHelper()); }
    }

    /// <summary>
    /// <see cref="Repository"/>
    /// </summary>
    protected Repository Repository
    {
        get { return _repository ?? (_repository = new Repository()); }
    }
}

注意惰性实例化。这允许我在运行测试之前潜入并使用模拟设置我的私有字段。

对于会话,您的User对象仍然可以像在传统的ASP.NET应用程序中一样保存在会话中。几乎所有内容仍然存在(响应,缓存,会话等),但其中一些已经被System.Web.Abstractions中的类包装,因此可以模拟它们进行测试。它们仍然以相同的方式运行,但您不应该使用它们的传统角色(例如,不要使用Response.Redirect,返回执行重定向的RedirectToRouteResult等ActionResult)。

至于你的问题背后的推理......

不要强调单个数据库连接。根据您的实施情况,它甚至可能是个坏主意,因为请求可能会相互衔接。只需打开你的连接器,使用它,并在完成后处理/关闭它。

此外,MVC带来的最大变化之一是拒绝传统ASP.NET试图为Web开发带来的有状态模型。所有的框架和视图状态都不再存在(不关注幕后的人)。您对Web应用程序不太复杂且更健壮的状态越少。尝试一下,你可能会喜欢它。

答案 1 :(得分:4)

如果您使用会话,我建议您使用会话类,这样您只需要在代码中指定一次字符串名称,这也会为您提供IntelliSence。

 public static class SessionHandler
{   
    // User Values
    private static string _userID = "UserID";
    private static string _userRole = "UserRole";

    public static string UserID
    {
        get
        {
            if (HttpContext.Current.Session[SessionHandler._userID] == null)
            { return string.Empty; }
            else
            { return HttpContext.Current.Session[SessionHandler._userID].ToString(); }
        }
        set
        { HttpContext.Current.Session[SessionHandler._userID] = value; }

    }

    public static string UserRole
    {
        get
        {
            if (HttpContext.Current.Session[SessionHandler._userRole] == null)
            { return string.Empty; }
            else
            { return HttpContext.Current.Session[SessionHandler._userRole].ToString(); }
        }
        set
        { HttpContext.Current.Session[SessionHandler._userRole] = value; }

    }
}

答案 2 :(得分:2)

在MVC中,会话根本没有改变。 Global.asax中的GlobalApplication类也存在。还存在一些页面,您希望引用控制器而不是页面中的存储库。将属性添加到基本控制器类很好;我一直这样做。

答案 3 :(得分:1)

您可以创建一个模型绑定器来封装状态。

(参见Steve Sanderson关于购物车实施的mvc书)

使用模型绑定器,您可以访问controllerContext - 它具有HttpContext。