ASP.NET C# Static Variables are global?
Today I released a small asp.net beta web application which allows internal staff to modify some product information. We started running into issues where users were overwriting each others product information... even though each staff member was editing a totally different row (Product).
After some searching on google, I think I know what is going on, its to do with the use of static variables, below is a quick rough example of the problem:
// EditProductGroup.aspx.cs
public partial class EditProductGroup : System.Web.UI.Page
{
private static int _groupId = 0;
protected void Page_Load(object sender, EventArgs e)
{
_groupId = Convert.ToInt16(Request.QueryString["GroupID"]);
// get existing ProductGroup information from database using
//_groupId to find the row and populate textboxes
}
private void saveProductGroupData()
{
// when user hits 'save changes' button, update row
//where the primary key column 'ProductGroupID' matches _groupId in the table
}
}
So, according to my research, a static variable actually exists to the application as a whole, that means that if multiple users are using the application they will effectively all be reading the same 'value' for '_groupId' and in some cases actually setting it to a different value causing another users 'instance' of the page to save data to the wrong row (ProductGroupId).
My intention was that the static variable is isolated from other users, and should not intefere - each user has their own instance of the page thus their own instance of the '_groupId' variable.
Luckily it was all taking place on a dev/staging database not the live db. I'm not sure whether I just need to drop off the 'static' keyword to stop the variable being set/read by everyone.
Any thoughts? Thanks
Solution 1:
Yes, in ASP.NET a static fields lifetime is for the app domain (note that this differs a bit for generic types).
I'd recommend using the server Session for storage of data you want to associate with an instance of a client browser session (user login). i.e.
Session["_groupID"] = Convert.ToInt16(Request.QueryString["GroupID"]);
you can retrieve it by doing:
short groupID = Convert.ToInt16(Session["_groupID"]);
Solution 2:
It's incorrect to say that a static variable exists application wide. They in fact exist at two different levels
- For non-generic types there is a single static variable per AppDomain
- For generic types there is one per generic instantiation per AppDomain
An application can contain many AppDomains and is true in several types of applications.
If you want to store user specific settings though, use a Session variable.
Solution 3:
Static variables has the same lifetime as an application domain they were created in. So if you get some wrong values it can be some problems in the application logic or else. You should use SessionState for per-user data.
Solution 4:
You may want to take some time to familiarize yourself with what the static keyword is responsible for in C#. Read here: static in different languages and MSDN here.