ASP.NET : Session VS Static Property - A Fanny Story
As I was a beginner, I faced many technical hurdles and made mistakes that nowadays seem to be silly, but now I understand that they are part of my journey. Without this courage, I would not have gotten here.
When I had my first experience with ASP.NET, it was in 2007, and the version was 1.1.
With no senior guidance, but googling and searching, I dove into the .NET world and started to create a commercial project from scratch.
Now, I say thanks to my 22-year-old self for all his efforts and resilience.
And one mistake I will share here.
Users and login were a key part of this project, and keeping the user logged in was fundamental.
I was coming from PHP, and I already knew about sessions, and that's exactly how I used to keep the ID of the user logged in.
But when I started out with C#, I realized that it has static properties. In the first moment, what I just thought was “Why don't I keep the user ID in a static property?” It is easter than Session.
And for a beginner in ASP.NET, sessions seemed to be more difficult than PHP.
So I took this decision, and kept the user logged in a static class.
At first glance, it seemed to be working well. I was just testing on my local machine, logging and dislogging, and it worked perfectly.
However, when I published the site, and the users came to use it for the first time, a scary thing happened.
The second user overwrote the first, and the first user was logged as if it were the second.
Right away, I realized that it could be due to keeping the user in a static class, and I went straight to the point, and replaced the static class with sessions, and then it resolved.
So, I learned the hard way that there is a difference between using Session and Static Class
What happens is that an ASP.NET Web Forms application is one instance running on the server, and all requests access the same instance running. And as a consequence, all static items are shared for all the requesters.
On the other hand, sessions are kept separately for each requester, but shared between tabs.
Here is the session definition by ChatGPT:
Session refers to a server-side storage of information that is used to maintain a user's state and data across multiple requests within a web application. It begins when a user accesses the site and ends when they leave, log out, or after a period of inactivity. Sessions are typically identified by a unique session ID stored in a browser cookie or URL.
And here is an example of how to set and get a session value:
Nowadays, one way for handling user login is the bearer token, which will be a topic for one of my next posts.
Thanks for reading my content, if my content is helpful for you, please don’t help but let it a like, then I can know that!
Add the keyword “session“ to your comment so I can know you read it.
Have a blissful day!
Software Enginner | Node.js | JavaScript | TypeScrit | AWS
3wThanks for sharing, Cassio Almeron
Software Engineer | Python, Django, AWS, RAG
1moGreat share—your real-world example highlights perfectly why session is designed for user-specific data and static properties belong only to global application state—essential lessons for avoiding cross-user vulnerabilities in ASP. NET
Mobile Senior Software Engineer | Android, Java/Kotlin, IOS Swift
1moReally enjoyed this story—there’s no better teacher than the production environment! It’s so easy to underestimate how differently a Web Forms app behaves once real users start hitting it in parallel. I’ve seen several newcomers fall into the same trap of storing per-request data in static members: it seems harmless during local testing, but under load every request shares the same static context, so one user’s data overwrites another’s. It drives home why session state exists in ASP.NET: it’s scoped to a single browser session (via a cookie-based session ID) yet shared across that user’s requests and tabs. Your quick fix—replacing the static property with Session["UserId"]—perfectly illustrates the difference between application-wide state (statics, cache, app settings) and per-user state (sessions, cookies, tokens). Today we often lean on stateless JWT/Bearer tokens or server-side distributed caches, but the core lesson remains: understand your scope and thread model before choosing where to store something. Thanks for sharing a real-world “gotcha” that every .NET newcomer should hear—it might just save someone’s first production rollout!
Senior Software Engineer | PHP | Laravel | Vue.js
1moGreat content!
Mobile Software Engineer | React Native | React
1moC# was my first programming language. Amazing.