We have various related session variables for a complex page that has various things going on. Currently these session values are individual page properties (Guid, String, Integer etc). If I had a serializable object with these properties and saved this in the session, would it be more efficient?
No problem as long as the class is small and compact and is not much functional. You can create immutable structure to this if you need not alter the values once created more frequently. You can always overwrite with new structure upon any modification.
Here's some code.
public struct MyStruct
{
public string MyProp;
public MyStruct(string myProp)
{
this.MyProp = myProp;
}
}
public MyStruct MyStructInSession
{
get
{
if (Session["_MyStructInSession"] == null)
{
Session["_MyStructInSession"] = new MyStruct("unnamed");
//or you can throw an exception but that's not adviseble.
//throw new Exception("Nothing stored in session");
}
return (MyStruct)Session["_MyStructInSession"];
}
set
{
Session["_MyStructInSession"] = value;
}
}
If performance is a major concern, then you may want to look at optimizing the serialization of the session content. Serialization/deserialization becomes a bigger bottleneck when you scale out to a Session Server or use SQL Server to manage session state.
From MSDN Magazine:
Session state uses a custom serialization mechanism to convert the session dictionary and its contents to a binary blob before storing the data in an out-of-process store. The serialization mechanism has direct support for .NET Framework primitive types, including String, Boolean, DateTime, TimeSpan, Int16, Int32, Int64, Byte, Char, Single, Double, Decimal, SByte, UInt16, UInt32, UInt64, Guid, and IntPtr. These types are written directly to the blob, while object types are serialized with BinaryFormatter, which is slower. Deserialization follows the same rules. By optimizing the session contents, you can significantly reduce the overhead of serialization and deserialization of the state data.
When designing your session object model, avoid storing object types in the session. Instead, only store primitive types in the session dictionary and rebuild your business layer session objects on every request based on the session data. This avoids the overhead of using BinaryFormatter.
As always, measure your performance first before making any optimizations.
It's unlikely to be a problem but you might consider storing page specific values in ViewState instead.
I create a static class called SessionInfo that wraps access to session variables, for example:
public static class SessionInfo
{
private const string AUDITOR_ID_KEY = "AUDITOR_ID_KEY";
private static T GetSessionObject<T>(string key)
{
object obj = HttpContext.Current.Session[key];
if (obj == null)
{
return default(T);
}
return (T)obj;
}
private static void SetSessionObject<T>(string key, T value)
{
if (Equals(value, default(T)))
{
HttpContext.Current.Session.Remove(key);
}
else
{
HttpContext.Current.Session[key] = value;
}
}
public static int AuditorId
{
get { return GetSessionObject<int>(AUDITOR_ID_KEY); }
set { SetSessionObject<int>(AUDITOR_ID_KEY, value); }
}
}