views:

6086

answers:

10

What is the best way to check for the existance of a session variable in ASP.NET C#?

I like to use String.IsNullOrEmpty works for strings and wondered if there was a similar method for Session. Currently the only way I know of is:

 var sSession;
 if (Session["variable"] != null)
 {
     sSession = Session["variable"].ToString();
 }
 else
 {
     sSession = "set this";
     Session["variable"] = sSession;
 }
+5  A: 

That is pretty much how you do it. However, there is a shorter syntax you can use.

sSession = (string)Session["variable"] ?? "set this";

This is saying if the session variables is null, set sSession to "set this"

Ely
you can't do this... Session["variable"] is an Object and the compiler will then convert it to a String because sSession is a String, if the Session["variable"] does not exist, it throws an exception!
balexandre
You are absolutely correct. I updated the code to cast the string if Session is not null.
Ely
+1  A: 

Checking for nothing/Null is the way to do it.

Dealing with object types is not the way to go. Declare a strict type and try to cast the object to the correct type. (And use cast hint or Convert)

 private const string SESSION_VAR = "myString";
 string sSession;
 if (Session[SESSION_VAR] != null)
 {
     sSession = (string)Session[SESSION_VAR];
 }
 else
 {
     sSession = "set this";
     Session[SESSION_VAR] = sSession;
 }

Sorry for any syntax violations, I am a daily VB'er

StingyJack
A: 

Are you using .NET 3.5? Create an IsNull extension method:

public static bool IsNull(this object input)
{
    input == null ? return true : return false;
}

public void Main()
{
   object x = new object();
   if(x.IsNull)
   {
      //do your thing
   }
}
Michael Kniskern
That could be written:public static bool Is(this object input){ return input == null;}
James Curran
You should be careful with extension methods.
Chris Pietschmann
Why should I be careful with extension methods?
Michael Kniskern
A: 

If you know it's a string, you can use the String.IsEmptyOrNull() function.

Kevin Pang
+7  A: 

It may make things more elegant to wrap it in a property.

string MySessionVar
{
   get{
      return Session("MySessionVar") ?? String.Empty;
   }
   set{
      Session("MySessionVar") = value;
   }
}

then you can treat it as a string.

if( String.IsNullOrEmpty( MySessionVar ) )
{
   // do something
}
Greg Ogle
This is what I do, makes it much easier to access session vars in an app. I tend to make classes for the data, and static properties which do all the null check grunt work.
Rob Cooper
What if you are storing an object in the Session and not just a string?
Aaron Palmer
See my answer, the use of generics enables type-safety when storing other objects.
Rob Cooper
A: 

my recommendation is:

in your Utilities Class add this:

public static class Utilities
{
    public static String GetSessionValue(object session)
    {
        String r = "";
        try { r = session.ToString(); }
        catch (Exception) { }
        return r;
    }
}

Then all you need to do is call this function like:

sSession = Utilities.GetSessionValue(Session["variable"]);
balexandre
"Utilities" is bad! :P Call it a proper name! I will post some code in a answer as well..
Rob Cooper
sometimes I called Helpers :D
balexandre
You shouldn't check your session with a try ... catch.... Very bad performance.
TheGeekYouNeed
A: 

Typically I create SessionProxy with strongly typed properties for items in the session. The code that accesses these properties checks for nullity and does the casting to the proper type. The nice thing about this is that all of my session related items are kept in one place. I don't have to worry about using different keys in different parts of the code (and wondering why it doesn't work). And with dependency injection and mocking I can fully test it with unit tests. If follows DRY principles and also lets me define reasonable defaults.

public class SessionProxy
{
    private HttpSessionState session; // use dependency injection for testability
    public SessionProxy( HttpSessionState session )
    {
       this.session = session;  //might need to throw an exception here if session is null
    }

    public DateTime LastUpdate
    {
       get { return this.session["LastUpdate"] != null
                         ? (DateTime)this.session["LastUpdate"] 
                         : DateTime.MinValue; }
       set { this.session["LastUpdate"] = value; }
    }

    public string UserLastName
    {
       get { return (string)this.session["UserLastName"]; }
       set { this.session["UserLastName"] = value; }
    }
}
tvanfosson
+16  A: 

To follow on from what others have said. I tend to have two layers:

The core layer. This is within a DLL that is added to nearly all web app projects. In this I have a SessionVars class which does the grunt work for Session state getters/setters. It contains code like the following:

    public class SessionVar
    {
    static HttpSessionState Session
    {
        get
        {
            if (HttpContext.Current == null)
                throw new ApplicationException("No Http Context, No Session to Get!");

            return HttpContext.Current.Session;
        }
    }

    public static T Get<T>(string key)
    {
        if (Session[key] == null)
            return default(T);
        else
            return (T)Session[key];
    }

    public static void Set<T>(string key, T value)
    {
        Session[key] = value;
    }
    }

Note the generics for getting any type.

I then also add Getters/Setters for specific types, especially string since I often prefer to work with string.Empty rather than null for variables presented to Users.

e.g:

public static string GetString(string key)
    {
        string s = Get<string>(key);
        return s == null ? string.Empty : s;
    }

    public static void SetString(string key, string value)
    {
        Set<string>(key, value);
    }

And so on...

I then create wrappers to abstract that away and bring it up to the application model. For example, if we have customer details:

public class CustomerInfo
{
    public string Name
    {
        get
        {
            return SessionVar.GetString("CustomerInfo_Name");
        }
        set
        {
            SessionVar.SetString("CustomerInfo_Name", value);
        }
    }
}

You get the idea right? :)

NOTE: Just had a thought when adding a comment to the accepted answer. Always ensure objects are serializable when storing them in Session when using a state server. It can be all too easy to try and save an object using the generics when on web farm and it go boom. I deploy on a web farm at work so added checks to my code in the core layer to see if the object is serializable, another benefit of encapsulating the Session Getters and Setters :)

Rob Cooper
Thanks for providing thorough answers. Very nice!
Torbjørn
No problem, HTH :)
Rob Cooper
Great approach! I have been using something similar for a long time, but hadn't incorporated generics. This avoids so many problems with different developers creating similar Session variables.
DOK
A: 

The 'as' notation in c# 3.0 is very clean. Since all session variables are nullable objects, this lets you grab the value and put it into your own typed variable without worry of throwing an exception. Most objects can be handled this way.

string mySessionVar = Session["mySessionVar"] as string;

My concept is that you should pull your Session variables into local variables and then handle them appropriately. Always assume your Session variables could be null and never cast them into a non-nullable type.

If you need a non-nullable typed variable you can then use TryParse to get that.

int mySessionInt;
if (!int.TryParse(mySessionVar, out mySessionInt){
   // handle the case where your session variable did not parse into the expected type 
}
Aaron Palmer
+1  A: 

I also like to wrap session variables in properties. The setters here are trivial, but I like to write the get methods so they have only one exit point. To do that I usually check for null and set it to a default value before returning the value of the session variable. Something like this:

string Name
{
   get 
   {
       if(Session["Name"] == Null)
           Session["Name"] = "Default value";
       return (string)Session["Name"];
   }
   set { Session["Name"] = value; }
}

}

Rune Grimstad