The ASP.Net Session state is a pretty nice way to store (limited) amount of data on the server-side. I am not going to introduce the ASP.Net session itself in this post; you can refer to the previous link if you have no idea what I am talking about.
Although many articles can be found over the web arguing that the major issue with the session state is scalability, don't believe them! Well, as long that you're not doing crazy things like storing your whole DB in the session state which is not too hard to avoid. Additionnally, 3rd party providers (see ScaleOut for example) seem to offer pretty much plug&play solutions if you're in desperate need for more session space (disclaimer: I haven't tested myself any of those products).
In my (limited) experience, I have found that the main issue with the Session State is the lack of strong typing. Indeed, lack of strong-typing has a lot of painful consequences such as
- Hard collisions: The same session key gets used to store 2 distinct objects of different .Net types. This situation is not too hard to debug because the web application will crash in a sufficiently brutal way to be quickly detected.
- Smooth session collisions: The same session key gets used to store 2 distinct objects of the same type. The situation is really worse than the previous case because, if you're unlucky, your web app will not crash. Instead your users will just experience very weird app behaviors from time to time. The multi-tab browsing users will be among the first victims.
- No documentation: static field get documented, right? There is no good reason to discard Session State documentation.
- No refactoring: Errare Humanum Est, session keys do get poorly or inconsistently named like any other class/method/whatever. No automated refactoring means that the manual refactoring attempts will introduce bugs with a high probability.
A simple approach to solve most of those issues consists of strong typing your sessions keys. This can be easily achieved with the following pattern:
partial class MyPage : System.Web.UI.Page
// Ns = the namespace, SKey = SessionKey
const string Foo1SKey = "Ns.MyPage.Foo1";
const string Foo2SKey = "Ns.MyPage.Foo2";
Instead of explicitly typing the session key, the
const string fields get used instead. If you need to share session keys between several pages then a dedicated class (gathering the session keys) can be used following the same lines. This pattern basically solves all the issues evocated here above.
- Collisions get avoided because of the combination of namespace and class prefixes in the session key definitions (*).
- Documentation is straightforward, just add a
<summary/>documentation tag to the const string definition.
- Refactoring is easy, just refactor the field or change its value (depending on the refactoring intent).
(*) It would have been possible to prefix directly in the code all session keys by the very same combination of namespace and class name, but it becomes a real pain if you start using the session frequently in your code.