views:

2070

answers:

4

Hi guys...

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

+7  A: 

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"]);
Adam Markowitz
Thanks Adam .... the only thing is, I don't really need to store this for use in other pages, I would just wanted to store the contents of 'Request.QueryString["GroupID"]' into a variable that I can use anywhere within just that page...without it being changed by 'other' user's instances of the page... Would "private _groupId" (omitting the static keyword) allow for this? If not then I guess I could use Sessions. Thanks for the input!
Dal
Dal - Session variables, as you suspect, are kept around regardless of the page being viewed for the entirety of the client browser session (unless you expire them manually). You could use ViewState to store the value, however it is streamed to the client (with its default settings) so there is a chance it could be mucked with (however unlikely). ViewState would keep the value on a per page basis. Is there a reason you just can't continue to use the QueryString value you are initially using? For your situation I'd recommend QueryString, ViewState, HiddenField or Session for storage.
Adam Markowitz
Thanks for the quick reply. The application has been modified to use the querystring directly rather than pushing it into a variable so yes I think I will continue to use this method (QueryString). I was just curious as to whether my original implementation would still work without the static keyword. Thanks a lot! :)
Dal
Dal, if you are merely using this as temporary storage for the groupID per request you can just remove the static keyword. This will make the field a member of the page instance. If you want to load the value of the groupID and store it across postbacks to the same page you can use the other options. Either way, good luck!
Adam Markowitz
+2  A: 

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.

Restuta
+2  A: 

You may want to take some time to familiarize yourself with what the static keyword is responsible for in C#. Read here: http://stackoverflow.com/questions/620024/static-in-different-languages and MSDN here.

LBushkin
+8  A: 

It's incorrect to say that a static variable exists application wide. They in fact exist at two different levels

  1. For non-generic types there is a single static variable per AppDomain
  2. 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.

JaredPar