Click here to Skip to main content
15,881,684 members
Articles / Web Development / ASP.NET
Article

Exploring ASP.NET Session State and Cache data

Rate me:
Please Sign up or sign in to vote.
4.57/5 (26 votes)
10 Jan 2007CPOL7 min read 363.5K   6.3K   131   45
An article showing how to create quick, "easy to use" views of session state and cache.

Introduction

On all the previous ASP and ASP.NET web sites I have worked on I have thought how useful it would be to have some quick and "easy to use" view of Session State and the Cache without having to sit with the debugger and manually step through each one.

As soon as you get a few developers working on a site you face the possibility of session and/or cache abuse. By this I do not mean to suggest that anything malicious might be going on, simply that there is the potential for sloppy use of these facilities. For example, putting information into session state that really shouldn't be in there or multiple developers putting identical data into session state under separate keys.

Under these circumstances it would be useful to have one or more utilities to allow you to view the contents of session state and the cache.

In this article I will show how to create these quick, "easy to use" views of session state and cache. Along the way we will touch on the subjects of HttpHandlers, custom configuration sections and binary serialization.

The full source code and a test web site is available to download.

Extending a Good Idea

Both our session and the cache views are implemented in a similar way to the standard trace tool that comes with ASP.NET, trace.axd.

The ASP.NET trace functionality is available to use in you ASP.NET code through the TraceContext class and the Page class’ Trace property. Information output to trace and a lot of other useful information such as an enumeration of session variables is rendered by the TraceHandler class that deals with the processing of the virtual page Trace.axd. The MSDN Online documentation on trace is here ASP.NET Trace.

Our session and cache views are custom HttpHandlers that are configured to process requests for the virtual pages of SessionView.axd and CacheView.axd. These names are determined using local web.config setting and the choice of them is up to the developer. I have given my "pages" an axd extension simply for consistency with the already well-known trace.axd. The article Extending ASP.NET with HttpHandlers and HttpModules from http://www.devx.com/ does a great job of explaining how to create a custom HttpHandler so I will not be covering that here.

The configuration xml to add the HttpHandlers to the ASP.NET pipeline is:

XML
<httpHandlers>
<add verb="*" 
path="SessionView.axd"
type="Charteris.Web.HttpHandlers.SessionViewHandler,Charteris.Web.HttpHandlers" />
<add verb="*" 
path="CacheView.axd" 
type="Charteris.Web.HttpHandlers.CacheViewHandler,Charteris.Web.HttpHandlers" />
</httpHandlers>

If the HttpHandler's assembly was located in the Global Assembly Cache (GAC) you would need to add further location information with the type attribute changing from

type="Charteris.Web.HttpHandlers.SessionViewHandler,
      Charteris.Web.HttpHandlers"

to

type="Charteris.Web.HttpHandlers.SessionViewHandler,
      Charteris.Web.HttpHandlers, Version=2.0.2000.0, 
      Culture=neutral, 
      PublicKeyToken=4edafd72b7cb8805"

This extra GAC information is available from Windows Explorer when you browse to the %WindowsDir%\Assembly directory.

For security reasons I have implemented a check to ensure only requests from the local box are processed. These are really only dev tools so this restriction is not really an issue. The RequestIsLocal code is in the Common.cs class and simply checks if the request’s source IP address is the local loopback address of 127.0.0.1 or if it is the same as the server’s IP address.

C#
///<summary>
/// Check if current request originated locally
///</summary>
///<param name="request">The current HttpRequest</param>
///<returns>True if the request originated locally</returns>
internal static bool RequestIsLocal(HttpRequest request){ 
    if(request.UserHostAddress == "127.0.0.1" || 
        request.UserHostAddress == request.ServerVariables["LOCAL_ADDR"]){ 
            return true; 
    } 
    else{ 
        return false; 
    } 
} 

The views both have a similar configuration style with the ability to disable the view and to disable the link, which allows viewing of the actual data stored within the session state or cache item. This link can be seen in the SessionView.axd screenshot in the following section.

These configuration options are implemented using a custom config handler. Custom config handlers inherit from IConfigurationSectionHandler and are used to process the config section that you set up in web.config. In the following piece of XML I have defined the config section and what handler will process it. Again the type attribute would need extra information if the config handler's assembly was in the GAC. The MSDN online docs for creating and processing custom config sections are very good and can be found here Creating New Configuration Sections.

As you may be aware Microsoft occasionally release best practice .NET code known as Application Blocks. There is a new block due for release this summer that deals with custom configuration, in .NET, using your own custom config files. If there is enough interest I will do an update to this article that uses the new Microsoft application block to handle the view's configuration needs.

SessionView.axd

Image 1

The session state view enumerates all the items in Session State.

For each item it will render a row containing the item’s key in the session state collection and its type name.

If the Session State mode being used means that the items are serialized into the session state then it will also display an approximation of the storage space the object is taking up. When Session State is running InProc (In Process) the actual objects that form the content are not stored in the collection, only reference to the objects. The figures for the size taken up by these objects "in" session state would be misleading under these circumstances. Therefore there is no "Object Size" column when running in this mode. When Session State is running out of process, either using a StateServer machine or a SQL Server database, the objects are serialized into Session State.

The value that is displayed in the "Object Size" column is the byte size of a stream that is used as the destination of a binary serialization. This code to perform the serialization for most objects is shown below:

C#
MemoryStream m;
m = Common.BinarySerialize(sessionItem);

//Size value
double size = Convert.ToDouble(m.Length) / Convert.ToDouble(1000) + " KB"; 

/// <summary>
/// Serialize object into a memory stream using Binary Serialization
/// </summary>
/// <param name="objectToSerialize">object to serialize</param>
/// <returns></returns>
internal static MemoryStream BinarySerialize(object objectToSerialize) {
    MemoryStream m = new MemoryStream();
    BinaryFormatter b = new BinaryFormatter();

    b.Serialize(m, objectToSerialize);

    return m;
}

Originally I was the above technique, for all types stored in Session and Cache, to get my calculations for approximate "Object Size". However after some discussion with one of the Microsft devs in the US I now know that ASP.NET uses an internal, optimized, serialization technique for some of the standard types. This technique is internal to the System.Web assmebly and is subject to change in future versions. I have imitated their approach and have listed below all the types that are currebtly being serialized in this fashion. This set of types is correct for the 1.1 version of the framework. Less types were serialised in this way in version 1.0.

  • String
  • Int16
  • Int32
  • Int64
  • Boolean
  • DateTime
  • Decimal
  • Byte
  • Char
  • Double
  • SByte
  • UInt16
  • UInt32
  • UInt64
  • Timespan
  • Guid
  • IntPtr
  • UIntPtr
  • Object

If the item’s type can be understood by the XmlSerializer class then the “View Data” cell will display a link to allow viewing of the contents of the item. This facility can be disabled by setting the config attribute showViewDataLink to false. I use the XmlSeriliazer to get a renderable view of the data. This means that there are extraneous XML tags at the top and bottom of the data when viewed.

CacheView.axd

Image 2

In a similar fashion to the session state view, this enumerates the contents of the cache.

Again for every cache item, it will render a row containing the item’s key in the cache collection and its type name. As the cache is always run in process, the items are object references and therefore there is no “Object Size” column for the cache view.

Again like the session view, if it is not disabled by the config setting showViewDataLink and the item’s type is understood by the XmlSerializer, the “View Data” cell will display a link to allow viewing of the contents of the item.

Points of Interest

One gotcha that I found with developing an HttpHandler that wants to use session state was that by default you can’t. If you want your HttpHandler to have access to session state you need to implement the IRequiresSessionState interface.

History 

OK, After speaking to one of the Microsoft guys in the US there is a serious flaw in my thinking regarding calculating an approximate size for items in session state. ASP.NET "uses an optimized internal formatter for basic types such as int, string, bool, etc". Therefore me basing my calculation on the BinaryFormatter is wrong. I have updated the article saying that my use of the BinaryFormatter gives only a very rough approximation.

  • 31 May 2003 - updated downloads
  • 6 June 2003 - Amended Text

The article now takes into consideration that ASP.NET uses an internal optimized serialization technique for the many of the base types.

I have also fixed a bug where some or all parts of the data would not appear in the browser. This was fixed by HTML encoding the output using HttpServerUtility.HtmlEncode.

  • 10 Jan 2007 - Updated source file to include missing project

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Europe Europe
I have been programming now for 10 years starting with COBOL, CICS and DB2 and ending up with ASP.NET, WPF, and various web technologies.

I work for Munkiisoft in the UK.

Check out my blog here

Comments and Discussions

 
QuestionSee size in session? Pin
coolguyrob11-Oct-04 16:14
coolguyrob11-Oct-04 16:14 
GeneralFormatted XML Output Pin
matzy23-Apr-04 7:37
matzy23-Apr-04 7:37 
GeneralRe: Formatted XML Output Pin
Patrick Long26-Apr-04 2:36
Patrick Long26-Apr-04 2:36 
GeneralCache Pin
matzy23-Apr-04 7:23
matzy23-Apr-04 7:23 
Generaldot.net/VS version? Cannot open solution! Pin
manfbraun16-Jul-03 21:08
manfbraun16-Jul-03 21:08 
GeneralRe: dot.net/VS version? Cannot open solution! Pin
Patrick Long16-Jul-03 23:41
Patrick Long16-Jul-03 23:41 
GeneralRe: dot.net/VS version? Cannot open solution! Pin
manfbraun17-Jul-03 0:50
manfbraun17-Jul-03 0:50 
GeneralRe: dot.net/VS version? Cannot open solution! Pin
Patrick Long17-Jul-03 21:22
Patrick Long17-Jul-03 21:22 
Manfred

In what way does "But all aspx-coders should reall learn more CSS...." relate to my article?

That is not to say I think i am some CSS god just that I was unclear what you were getting at.

BTW the styles and classes are exactly those used by the Trace.axd that comes with ASP.NET

Pat
GeneralRe: dot.net/VS version? Cannot open solution! Pin
manfbraun18-Jul-03 8:42
manfbraun18-Jul-03 8:42 
GeneralRe: dot.net/VS version? Cannot open solution! Pin
Patrick Long20-Jul-03 5:50
Patrick Long20-Jul-03 5:50 
GeneralSession State unpreditable Pin
jmathew5-Jul-03 11:32
jmathew5-Jul-03 11:32 
GeneralRe: Session State unpreditable Pin
Patrick Long10-Jul-03 22:04
Patrick Long10-Jul-03 22:04 
GeneralError executing project Pin
Member 3957533-Jun-03 8:27
Member 3957533-Jun-03 8:27 
GeneralRe: Error executing project Pin
Patrick Long3-Jun-03 10:23
Patrick Long3-Jun-03 10:23 
QuestionSee size in cache? Pin
Paul Tallett29-May-03 22:18
Paul Tallett29-May-03 22:18 
AnswerRe: See size in cache? Pin
Patrick Long30-May-03 1:05
Patrick Long30-May-03 1:05 
GeneralRe: See size in cache? Pin
Patrick Long3-Jun-03 10:41
Patrick Long3-Jun-03 10:41 
GeneralRe: See size in cache? Pin
RandomHavoc29-Oct-04 10:45
RandomHavoc29-Oct-04 10:45 
GeneralRe: See size in cache? Pin
AllenRogerMarshall2-Mar-22 19:44
professionalAllenRogerMarshall2-Mar-22 19:44 
GeneralError Message opening up project Pin
JerryDairy28-May-03 6:58
JerryDairy28-May-03 6:58 
GeneralRe: Error Message opening up project Pin
Patrick Long28-May-03 10:39
Patrick Long28-May-03 10:39 
GeneralRe: Error Message opening up project Pin
lasthope838-Jan-07 5:30
lasthope838-Jan-07 5:30 
GeneralRe: Error Message opening up project Pin
Patrick Long9-Jan-07 9:54
Patrick Long9-Jan-07 9:54 
GeneralRe: Error Message opening up project Pin
Patrick Long15-Jan-07 13:09
Patrick Long15-Jan-07 13:09 
GeneralRe: Error Message opening up project Pin
Patrick Long1-Jun-03 11:16
Patrick Long1-Jun-03 11:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.