MVC's HttpContext object contains three collections that can hold onto data from one request to the next: Temp[], Session[], and Cache[]. They all use strings for their keys, and can store arbitrary objects (sometimes with limitations.)

Temp[] is used to hold a value for one-time use. Once the value is retrieved it is removed from the collection. A typical use would be to store a model object in a POST handler, redirect to a GET handler, and retrieve the model object from Temp[] to render it. (AB_BaseController provides am_StoreModelStateErrors and am_RestoreModelStateErrors to assist in this scenario by passing the ModelState object through Temp[] too, so that the GET handler can render validation errors that were discovered in the POST handler.)

Session[] is used to hold values for the duration of the user's session, or until they are explicitly removed. Storing a lot of data in Session[] can cause excess memory consumption on the server, limiting the number of concurrent sessions it can handle. To address this problem the session mode can be configured to store data in a standalone SessionServer system service or in MSSQL. If either of these modes are used, only [Serializable] objects can be stored in Session[]. (Typically Accelerator-based MVC applications that use user login will store the UserEntity and other user-related objects in Session[], but not all of that data is serializable, so only the In Process mode can be used.)

Cache[] is like Session[], except data can be set to expire and be removed automatically. Its Add() method lets you specify either an absolute expiration time or a sliding expiration timer (eg: time since last access.) It is also possible to specify a method which will be called when the item is removed from the cache.

private const string UNREAD_CACHE_KEY = "__MSG_Unread_Messages__";

public List<MSG_MessageEntity> UnreadMessages
{
    get
    {
        var msgs = HttpContext.Current.Cache[UNREAD_CACHE_KEY] as List<MSG_MessageEntity>;
        if (msgs == null)
        {
            // Real World: perform expensive database lookup here
            msgs = new List<MSG_MessageEntity>();

            TimeSpan expirationTime;
            if (!TimeSpan.TryParse(ConfigurationManager.AppSettings["Features.Messages.LookupFrequency"], out expirationTime))
            {
                expirationTime = new TimeSpan(0, 1, 0);
            }
            HttpContext.Current.Cache.Add(UNREAD_CACHE_KEY, msgs, null, DateTime.Now.Add(expirationTime), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
        }

        return msgs;
    }
}

See also: