views:

49

answers:

5

I have several variables that I need to send from page to page... What is the best way to do this?

Just send them one by one:

string var1 = Session["var1"] == null ? "" : Session["var1"].ToString();
int var2 = Session["var2"] == null ? 0 : int.Parse(Session["var2"].ToString());

and so on...

Or put them all in some kind of container-object?

struct SessionData
{
    public int Var1 { get; set; }
    public string Var2 { get; set; }
    public int Var3 { get; set; }
}

--

SessionData data = Session["data"] as SessionData;

What is the best solution? What do you use?

+4  A: 

A hybrid of the two is the most maintainable approach. The Session offers a low-impedance, flexible key-value pair store so it would be wasteful not to take advantage of that. However, for complex pieces of data that are always related to each other - for example, a UserProfile - it makes sense to have a deeply nested object.

Rex M
But why wouldn't you just store the userID or profileID in the Session and use the DB for the rest of it?
Christian W
Because then you incur the expense of the DB hit every time, which is arguably the slowest area of code.
JustLoren
A: 

I don't think I've every created an object just to bundle other objects for storage in a session, so I'd probably go with the first option. That said, if you have such a large number of objects that you need to bundle them up to make it easier to work with, you might want to re-examine your architecture.

chris
+1  A: 

If all the data that you're storing in the Session is related, then I would suggest consolodating it into a single object like your second example:

public class UserData
{
    public string UserName { get; set; }
    public string LastPageViewed { get; set; }
    public int ParentGroupId { get; set; }
}

And then load everything once and store it for the Session.

However, I would not suggest bundling unrelated Session data into a single object. I would break each seperate group of related items into their own. The result would be something of a middleground between the two hardline approaches you provided.

Justin Niessner
A: 

I've used both. In general, many session variable names leads to a possibility of collisions, which makes collections a litte more reliable. Make sure the collection content relates to a single responsibility, just as you would for any object. (In fact, business objects make excellent candidates for session objects.)

Two tips:

Define all session names as public static readonly variables, and make it a coding standard to use only these static variables when naming session data.

Second, make sure that every object is marked with the [Serializable] attribute. If you ever need to save session state out-of-process, this is essential.

Cylon Cat
+1  A: 

I use a SessionHandler, which is a custom rolled class that looks like this

public static class SessionHandler
{
    public static string UserId
    {
        get
        {
            return Session["UserId"];
        }
        set
        {
            Session["UserId"] = value;
        }
    }    
}

And then in code I do

var user = myDataContext.Users.Where(u => u.UserId = SessionHandler.UserId).FirstOrDefault();
JustLoren
If you're going to use this method, be sure to make it clear that the data is being kept in the Session. Otherwise, to other consumers of the class, the behavior will seem strange when the Session gets cleared.
Justin Niessner
Hopefully the name *Session*Handler clears that right up ;)
JustLoren