Keeping state - and not abusing the Session

I've seen a few applications lately using Session to communicate conversational state across pages. I've had a tough time putting this into words, but I truly believe this is wrong. If I'm mistaken here, please, I'd love to hear some other thoughts, but here's my initial thoughts on this space.

There are generally three classes of variables: those that are context-agnostic, those that are bound to a particular page, and those that fall somewhere in between (meaning the context boundary is a little broader than the page, but it still is bound to a context).

Only context-agnostic variables belong in the session.

The best example of what belongs in the session is probably a user's credentials. They truly are bound to the session - as in, a user doesn't change across pages.

But, credentials also have another important characteristic: recoverability. If the Session disappears, you can easily recover the user's credentials by asking him or her to login again and fetching the appropriate roles from wherever.

It's important to be defensive about Session variables.  Of course, it's important to be defensive in general, but it's even more important when you're dealing with something that's volatile like Session. In other words, don't assume Session variables exist. 

Other than session, there are two ways to shuttle state across pages - the QueryString or ViewState, or fundamentally, GET and POST.

As a general rule, unless the page needs to be URL addressable, conversational state should be done with a POST - especially if it is time-sensitive. I've seen a few applications lately that would set a primary key in a Session variable and then redirect to another page.

An important thing to consider when using Session is that it does not roll back when the user navigates with the browser back/forward buttons. Viewstate, of course, will - since the state is bound to that specific page.

Engineering