Click here to Skip to main content
Click here to Skip to main content

ASP.NET Session Helper (Scope, Categories)

, 9 May 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
Use scopes and categories to avoid collision and confusion between your session values.

Introduction (more about the ASP.NET session)

If you are developing ASP.NET web applications, you surely had to store and retrieve some persistent values belonging to each user navigating through your ASP.NET Web Application’s pages, so you naturally have used Session.

More information on using the Session is available here: MSDN

Session is nothing but a Dictionary (a collection based on key/value pairs) whose key type is a string and the value type is an object (i.e., any serializable object inheriting from object).

You can access the Session from "everywhere" using the current HTTP context System.Web.HttpContext.Current.Session or from the page’s shortcut reference in System.Web.UI.Page.Session.

Concretely, when you want to store a value in the Session, you may write such a line of code (without taking care of any session manager):

// Store value to session
int myValue = 10;
Session["MyKey"] = myValue;

Then, here is the code you may write to retrieve the previously stored value, mostly but not only from another page (or control):

// Retrieve value from session (up cast needed) 
int myValue = (int)Session["MyKey"];

Note that if you write you own class and want it to be stored to Session, you’ll need to add the [Serializable] attribute.

Session is raw, here is SessionHelper

As you see, Session is somewhat raw, and you’ll be quickly annoyed when you want to use advanced features such as categorized values, values belonging to a page or a control, etc.

In these cases, you should (you must) use the Session, but you should have some collision problems, a day or another!

A solution to this problem (let me know your feedback about it) is to use "scoped and categorized" session values. This is not a feature of the ASP.NET framework, but a session helper that I built and used with success, so I’m pleased to share this tip with you.

What is a "scoped and categorized" session value? Nothing but a session value whose key is generated from several parameters: its scope (for example: "Global"), its optional category (for example: "Filter"), and its handle/key (for example: "ItemsPerPage").

So, instead of using raw key / value pairs, we’ll use formatted key / value pairs this way (note that each token is separated by dots):

Session["Scope.Category.Key"]

  • Available scopes are the following (you can invent and implement yours):
    • Global (the same scope as raw session)
    • Page (current page, excluding query string parameters)
    • PageAndQuery (current page, including query string parameters)
  • Available scope’s categories are just limited to your imagination, for example, "Visitor" or "Filter" ones.
  • The key is the name / handle to the final value; choose a short and clear one, for example: "Surname".

Thus, here is the way to store a global value using this scheme:

/*
 *    In "OnePage.aspx"
 */
 
// Store value to session
Session["Global.Visitor.IPAddress"] = 
          HttpContext.Current.User.Identity.Name;
 
/*
 *    In "AnotherPage.aspx"
 */
 
// Retrieve value from session (up cast needed) 
string visitorIPAddress = 
       (string)Session["Global.Visitor.IPAddress"];

And, here is the code to restrict a stored value to a specific page (where "PageHash" is, for example, the MD5 or SHA-1 of the page’s URL):

/*
 *    In "OnePage.aspx"
 */
 
// Store page's filter value to session
Session["PageHash.Filter.Surname"] = textBoxSurname.Text;
 
/*
 *    In "AnotherPage.aspx"
 */
 
// Retrieve value from session (downcast needed), WILL NOT WORKS!!
string onePageSurnameFilter = (string)Session["PageHash.Filter.Surname "];
 
/*
 *    In "OnePage.asp"
 */
 
// Retrieve value from session (downcast needed), WORKS!!
textBoxSurname.Text = (string)Session["PageHash.Filter.Surname"];

The principle is good, but the method is still raw and now difficult to use, so, it’s time to implement the session helper class.

Implementing the helper

To implement the "scoped and categorized" functionality, I chose to build up a helper class named SessionHelper (don’ blame me for the lack of originality Wink | ;)

You can use this class directly in your pages, but I recommend you make base classes inheriting from the ASP.NET framework ones (System.Web.UI.*) and wrap this helper class inside them. If you haven’t already done that in your Web application, it will save you some boring code (this is explained in the "Wrapping the helper" section).

Let's start the code with the class body:

public class SessionHelper
{
    ...
}

As usual, let's start with enumerations. Here, I use one for the available scopes (global, to a page excluding query string, and to a page including query string):

...

#region Enumerators

/// <span class="code-SummaryComment"><summary></span>
/// Available session scopes
/// <span class="code-SummaryComment"></summary></span>
public enum Scope
{
    Global,
    Page,
    PageAndQuery
    /* put any other scopes you may find useful here */
}

#endregion

...

There are no instance members or accessors, so we can directly start to write static methods. In order to make an exhaustive class, we must allow developers to store, retrieve, search, and clear values, but internally, we must start by writing some private utility functions. The first thing to do is to generate the formatted key. Here, it is done through some overloaded methods:

#region Session's key format

/// <summary>
/// Format a key, using a scope a category and a key
/// </summary>
/// <param name="scope"></param>
/// <param name="category"></param>
/// <param name="key"></param>
/// <returns></returns>
private static string FormatKey(Scope scope, string category, string key)
{
    // clean up any points
    string scopeHash = GetScopeHash(scope);
    category = category.Replace(".", "");
    key = key.Replace(".", "");

    return string.Format("{0}.{1}.{2}", scopeHash, category, key);
}

/// <summary>
/// Format a key, using a category and a key (global scope)
/// </summary>
/// <param name="scope"></param>
/// <param name="key"></param>
/// <returns></returns>
private static string FormatKey(string category, string key)
{
    return FormatKey(Scope.Global, category);
}
 
/// <summary>
/// Format a key, using a scope and a key
/// </summary>
/// <param name="category"></param>
/// <param name="key"></param>
/// <returns></returns>
private static string FormatKey(Scope scope, string key)
{
    return FormatKey(scope, string.Empty);
}

/// <summary>
/// Format a key, using a key (global scope)
/// </summary>
/// <param name="scope"></param>
/// <param name="key"></param>
/// <returns></returns>
private static string FormatKey(string key)
{
    return FormatKey(string.Empty);
}

#endregion

You may have noticed a call to GetScopeHash; this method provides a hash corresponding to the given scope to avoid any collisions. Thus, "hard developers" will have to handle their custom scopes here, if needed (code below). Note that I call the GetHash method based on a MD5 hash (source: MSDN).

For its part, SessionKey provides a shortcut to HttpContext.Current.Session, according to the given scope, category, and handle.

StoreFormatedKey and ClearFormatedKey are low level methods to, respectively, store and retrieve a value to and from a formatted key.

Finally, ClearStartsWith is a helper method clearing all formatted keys, starting with the given string.

#region Cryptography

/// <span class="code-SummaryComment"><summary></span>
/// Creates a MD5 based hash
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="input"></param></span>
/// <span class="code-SummaryComment"><returns></returns></span>
private static string GetHash(string input)
{
    // step 1, calculate MD5 hash from input
    System.Security.Cryptography.MD5 md5 = 
           System.Security.Cryptography.MD5.Create();
    byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
    byte[] hash = md5.ComputeHash(inputBytes);

    // step 2, convert byte array to hex string
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < hash.Length; i++)
    {
        sb.Append(hash[i].ToString("X2"));
    }
    return sb.ToString();
}

#endregion

/// <span class="code-SummaryComment"><summary></span>
/// Get the hash of a scope
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><returns></returns></span>
private static string GetScopeHash(Scope scope)
{
    // Get scope name
    string scopeName = Enum.GetName(scope.GetType(), scope);

    switch (scope)
    {
        case Scope.Page:
            scopeName = HttpContext.Current.Request.Url.AbsoluteUri;
            if (HttpContext.Current.Request.Url.Query != string.Empty)
            {
                scopeName = scopeName.Replace(
                   HttpContext.Current.Request.Url.Query, "");
            }
            break;
        case Scope.PageAndQuery:
            scopeName = HttpUtility.UrlDecode(
               HttpContext.Current.Request.Url.AbsoluteUri);
            break;
    }

    return GetHash(scopeName);
}

/// <span class="code-SummaryComment"><summary></span>
/// Shortcut to formated session value
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><returns></returns></span>
private static object SessionKey(Scope scope, string category, string key)
{
    return HttpContext.Current.Session[FormatKey(scope, category, key)];
}                               

/// <span class="code-SummaryComment"><summary></span>
/// Rawly store a value in a formated key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="formatedKey"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
private static void StoreFormatedKey(string formatedKey, object value)
{
    HttpContext.Current.Session[formatedKey] = value;
}
 
/// <span class="code-SummaryComment"><summary></span>
/// Rawly clear a formated key value
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="formatedKey"></param></span>
private static void ClearFormatedKey(string formatedKey)
{
    HttpContext.Current.Session.Remove(formatedKey);
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears all formated keys starting with given value
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="startOfFormatedKey"></param></span>
private static int ClearStartsWith(string startOfFormatedKey)
{
    List<string> formatedKeysToClear = new List<string>();

    // Gather formated keys to clear
    // (to prevent collection modification during parsing)
    foreach (string key in HttpContext.Current.Session)
    {
        if (key.StartsWith(startOfFormatedKey))
        {
            // Add key
            formatedKeysToClear.Add(key);
        }
    }

    foreach (string formatedKey in formatedKeysToClear)
    {
        ClearFormatedKey(formatedKey);
    }

    return formatedKeysToClear.Count;
}

#endregion

It’s now time to check if a key exists (basically done by checking if the session value is null), with the help of these overloaded methods:

#region Key existence

/// <span class="code-SummaryComment"><summary></span>
/// Indicates if the key associated to given scope and category exists
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static bool Exists(Scope scope, string category, string key)
{
    return SessionKey(scope, category, key) != null;
}

/// <span class="code-SummaryComment"><summary></span>
/// Indicates if the key associated to given category exists (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static bool Exists(string category, string key)
{
    return Exists(Scope.Global, category, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Indicates if the key associated to given scope exists
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static bool Exists(Scope scope, string key)
{
    return Exists(scope, string.Empty);
}

/// <span class="code-SummaryComment"><summary></span>
/// Indicates if the key exists (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static bool Exists(string key)
{
    return Exists(string.Empty, key);
}

#endregion

Then, we provide some overloaded methods whose aim is to store values, according to the scope, category, and key (note that we use the StoreFormattedKey here):

#region Values storing

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope a category and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static void Store(Scope scope, string category, string key, object value)
{
    StoreFormattedKey(FormatKey(scope, category, key), value);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a category and a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static void Store(string category, string key, object value)
{
    Store(Scope.Global, category, key, value);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static void Store(Scope scope, string key, object value)
{
    Store(scope, string.Empty, key, value);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static void Store(string key, object value)
{
    Store(string.Empty, key, value);
}#endregion

After storing some values, the logical step is to retrieve them. To avoid some boring code to developers using our class, we’ll provide basic retrieving (Retrieve) and the ability to get a default value if the waited value doesn’t exist (RetrieveWithDefault):

#region Values retrieving (null if not found)

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope a category and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static object Retrieve(Scope scope, string category, string key)
{
    return SessionKey(scope, category, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a category and a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static object Retrieve(string category, string key)
{
    return Retrieve(Scope.Global, category, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static object Retrieve(Scope scope, string key)
{
    return Retrieve(scope, string.Empty, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static object Retrieve(string key)
{
    return Retrieve(string.Empty, key);
}

#endregion
 
 
#region Values retrieving (with default value)

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope a category and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static object RetrieveWithDefault(Scope scope, 
       string category, string key, object defaultValue)
{
    object value = SessionKey(scope, category, key);

    return value == null ? defaultValue : value;
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a category and a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static object RetrieveWithDefault(string category, 
                     string key, object defaultValue)
{
    return RetrieveWithDefault(Scope.Global, category, key, defaultValue);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a scope and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static object RetrieveWithDefault(Scope scope, 
              string key, object defaultValue)
{
    return RetrieveWithDefault(scope, string.Empty, key, defaultValue);
}

/// <span class="code-SummaryComment"><summary></span>
/// Stores a value to session, using a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static object RetrieveWithDefault(string key, object defaultValue)
{
    return RetrieveWithDefault(string.Empty, key, defaultValue);
}

#endregion

The last step is the capability to clear stored values. We can clear all values (Clear), the ones belonging to a scope (ClearScope), a scope’s category (ClearCategory), or simply to a key (Clear overloaded methods):

#region Values clearing

/// <span class="code-SummaryComment"><summary></span>
/// Clears all session values
/// <span class="code-SummaryComment"></summary></span>
public static void Clear()
{
    HttpContext.Current.Session.Clear();
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears all  session values of given scope
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><returns>Number of affected values</returns></span>
public static int ClearScope(Scope scope)
{
    return ClearStartsWith(string.Format("{0}.", GetScopeHash(scope)));
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears all session values of given scope's category
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
public static int ClearCategory(Scope scope, string category)
{
    return ClearStartsWith(string.Format("{0}.{1}.", 
                           GetScopeHash(scope), category));
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears all session values of given category (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
public static int ClearCategory(string category)
{
    return ClearCategory(Scope.Global, category);
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears a session value, using a scope a category and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static void Clear(Scope scope, string category, string key)
{
    Store(scope, category, key, null);
}
 
/// <span class="code-SummaryComment"><summary></span>
/// Clears a session value, using a category and a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="category"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
/// <span class="code-SummaryComment"><param name="value"></param></span>
public static void Clear(string category, string key)
{
    Clear(Scope.Global, category, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears a session value, using a scope and a key
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="scope"></param></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static void Clear(Scope scope, string key)
{
    Clear(scope, string.Empty, key);
}

/// <span class="code-SummaryComment"><summary></span>
/// Clears a session value, using a key (global scope)
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="key"></param></span>
public static void Clear(string key)
{
    Clear(string.Empty, key);
}

#endregion

That’s all folks!

Using the SessionHelper in your project

This helper class is easy to incorporate and use in your project. You can:

  1. move the class code in to your solution
  2. use the Initia.Web project included in the sample project
  3. compile and reference the Initia.Web project’s assembly.

Once you’ve done this, you may use the Initia.Web namespace like this:

using Initia.Web;

Then, you can start to use the helper class. Let’s say you have a couple of pages, and you want to count the total hits, each page’s hits, and the hits belonging to the click on a button.

First, create a page and go to the Page_Load event handler. We don’t have to bother about the IsPostBack state since we want to increment hits at each page load.

protected void Page_Load(object sender, EventArgs e)
{
    ...
}

Here is the code to retrieve the (implicit) global scope "Hits" session value, with the default value set to 0. Then, we store the incremented value:

...

// Incremented global session value
// (note that it doesn't scope with other "Hits" keys)
int totalHits = (int)SessionHelper.RetrieveWithDefault("Hits", 0);
SessionHelper.Store("Hits", totalHits + 1);

...

A very close code, using the SessionHelper.Scope.Page scope, can be written to be used in the scope of the current page (without bothering about the query string). Note that we’re using the same key, but there is no collision since we’re using another scope:

...

// Incremented current page session value
// (note that it doesn't scope with other "Hits" keys)
int currentPageHits = (int)SessionHelper.RetrieveWithDefault(
                       SessionHelper.Scope.Page, "Hits", 0);
SessionHelper.Store(SessionHelper.Scope.Page, "Hits", ++currentPageHits);

...

If you want to restrict the scope of some session values to the scope of the current page, including the query string, you may write this piece of code using the SessionHelper.Scope.PageAndQuery scope:

...

// Incremented current page session value
// (note that it doesn't scope with other "Hits" keys)
int currentPageQueryHits = (int)SessionHelper.RetrieveWithDefault(
                            SessionHelper.Scope.PageAndQuery, "Hits", 0);
SessionHelper.Store(SessionHelper.Scope.PageAndQuery, 
                    "Hits", ++currentPageQueryHits);
...

The last example is about categorized session values. This time, we’re going to increment a hits counter each time the user clicks on a button, and we’ll clear the category when the user clicks another button. Just add buttons in your page like this:

<asp:Button ID="btnAddUserHit" Text="Add hit to user category" runat="server" />
<asp:Button ID="btnClearUserCategory" Text="Clear user category" runat="server" />

Then, add an event handler in the code-behind (you can do it in the ASPX page, if you want):

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    // Events handlers

    btnAddUserHit.Click += new EventHandler(btnAddUserHit_Click);
    btnClearUserCategory.Click += new EventHandler(btnClearUserCategory _Click);
}

And finally, implement the event handlers like the following (UpdateUI is explained below):

#region Events handlers

private void btnAddUserHit_Click(object sender, EventArgs e)
{
    // Retrieves, increments then stores
    // categorized session value (default value is 0)
    int userHits = (int)SessionHelper.RetrieveWithDefault(
                        "User", "Hits", 0);
    SessionHelper.Store("User", "Hits", userHits + 1);

    // Update user interface
    UpdateUI();
}

private void btnClearGlobalCategory_Click(object sender, EventArgs e)
{
    SessionHelper.ClearCategory(SessionHelper.Scope.Global, "User");

    // Update user interface
    UpdateUI();
}

#endregion

As "bonus", here is a simple method updating the user interface according to the session values (just add a textbox with a tbUserHits ID in your ASPX page):

#region User interface

/// <span class="code-SummaryComment"><summary></span>
/// Update user interface
/// <span class="code-SummaryComment"></summary></span>
public void UpdateUI()
{
    // Show categorized session value (default value is 0)
    tbUserHits.Text = SessionHelper.RetrieveWithDefault("User", 
                                         "Hits", 0).ToString();
}

#endregion

Don’t forget to download the sample project; it covers most of the class capabilities, and will speed up the class integration in your project.

Points of interest / Conclusion

I hope this class will help you in your project and will save you some precious time.

If you don’t like my method and have a better one, please let us know in the comments are. If it helps you, please leave a comment and a mark to encourage me.

Thanks to

  • Rafael Rosa for fixing the encoding bug in the private static string GetScopeHash(Scope scope) method.

History

  • 2008 / 04 / 18 : First version.
  • 2008 / 04 / 19 : Added the "Use the SessionHelper in your project" section.
  • 2008 / 05 / 10 : Fixed the encoding bug in the private static string GetScopeHash(Scope scope) method (thanks to Rafael Rosa for his contribution). Both the class and the sample project have been updated.

License

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

Share

About the Author

Florian DREVET
Other euroCSgroup - Cabinet Zulian ICS
France France
I'm 30 year old, living at Saint-Maurice-de-Gourdans (France, near Lyon)
 
Research and Development manager
 
My hobbies are motorcycle (I'm riding a GSXF 750), Formula One, diescast Formula One models (mainly 1/18 scale), gardening, video games, and... software developement.
 
I started to make softwares about 15 years ago as a hobby, including now about 11 years of profesional activity. I worked for :
- a web agency
- a medical ISV (Independent Software Vendor), mainly in blood tracability department
- an online computer components seller
- actually in an engineering (and scientific advisory) ISV
 
I acquired several but complementary skills during this time, mainly (but not only) on Microsoft's technologies and platforms : assembly (x86, 68k), C, C++, C#, JavaScript, PHP, DBMS (MySQL, Oracle, SQL Server, etc.), etc.
 
Since 2007, I'm particulary active on .NET, ASP.NET, C#, SQL Server and ORM (NHibernate) with a growing time spent on architecture, technical managment, code review, etc.

Comments and Discussions

 
QuestionWhat is the advantage of using this sessionhelper? Pinmembersrinath g nath12-May-08 19:48 
AnswerRe: What is the advantage of using this sessionhelper? PinmemberFlorian DREVET13-May-08 2:04 
GeneralRe: What is the advantage of using this sessionhelper? PinmemberRafael Rosa Fu14-May-08 12:28 
GeneralRe: What is the advantage of using this sessionhelper? PinmemberFlorian DREVET15-May-08 22:05 
GeneralSessionHelper - Encoding Problems PinmemberRafael Rosa Fu8-May-08 6:40 
AnswerRe: SessionHelper - Encoding Problems PinmemberFlorian DREVET9-May-08 23:03 
GeneralSession helper PinmemberRafael Rosa Fu6-May-08 11:04 
GeneralRe: Session helper PinmemberFlorian DREVET9-May-08 23:00 
GeneralLooks useful PinmemberTonyDyer25-Apr-08 5:23 
GeneralRe: Looks useful PinmemberFlorian DREVET25-Apr-08 23:26 
GeneralGreat work - removing in scope Pinmembername for display only21-Apr-08 20:36 
GeneralRe: Great work - removing in scope PinmemberFlorian DREVET23-Apr-08 19:53 
GeneralClearing session values. PinmemberEdmundas Kevisas18-Apr-08 0:52 
GeneralRe: Clearing session values. [modified] PinmemberFlorian DREVET18-Apr-08 3:16 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.141015.1 | Last Updated 10 May 2008
Article Copyright 2008 by Florian DREVET
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid