简体   繁体   中英

Best Practice for storing data in an ASP.NET web page

I have a multi-user set of ASP.NET web pages. The pages use AJAX update panels so I can avoid updating the screen on every postback. The lifecycle of each page is as follows:
1. During Page_Load, get relevant data for user from a web service.
2. Store the data (quite large), and a service reference in a static dataset.
3. allow various edits to parts of the data via the screen controls (grids, text boxes)
4. validate data captured via form
5. send updated data back to service

I am doing this using static variables in the Page class itself as follows:

public partial class MyPage : System.Web.UI.Page
{
    static xxxx.DataCaptureServiceClient  m_Service; //reference to web service
    static string m_PersonID = string.Empty;  //current person_id page is viewing
    static ServResponse m_ServiceResult = null;        // reference to our data to edit ( ServResponse is a large data contract)   
    static string m_SortExpression = "Reference"; //default sort expression for grid

    const int PERSONID_COLUMN = 0;        //column index in grid for the personID column
    const int STATUS_COLUMN = 4;          //column index in grid for the application status

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (!Page.IsPostBack)
            {
                // Get new service instance.
                m_Service = new xxxx.DataCaptureServiceClient();

                ShowDataOnPage(); //get data in m_ServiceResult and bind to a grid on screen
            }
        }
        catch (Exception ex)
        {
            Response.Redirect("ErrorPage.aspx", false);
        }
    }

    protected void butNext_Click(object sender, EventArgs e)
    {
        try
        {
            Page.Validate();

            if (Page.IsValid)
            {
                // Use m_ServiceResult and m_Service to send a packaged submission to the service.
                SendDatatoService();
                Response.Redirect("TheNextPage.aspx", false);

            }
        }
        catch (Exception ex)
        {
           Response.Redirect("ErrorPage.aspx", false);
        }
}

//Other methods which allow edits to m_ServiceResult

I am wondering if:

A) This is a good way to implement or are there better practices?
B) Should I clear down memory by setting all statics to NULL when I redirect to another page?
C) If I clear down the statics do I risk another user losing data?

UPDATE

I have rewritten removing the statics, keeping the const values and passing data I need around as parameters. Where I need to keep data for updates I have kept the minimal amount I need in session[] variables.

A) No - what happens if a 2nd user opens a page while another one is busy? The static dataset will be overwritten with the 2nd user's data, or is your static dataset somehow differentiating different users' data at the same time?

B) If you absolutely must use statics / server side data, then yes, you should clear them somehow. Guaranteeing that this happens is difficult however. (Eg if one user just closes their browser)

C) Possibly, but if this is a concern then my question in A) is already going to cause greater problems for you.

As a general answer, storing large amounts of data in memory on the server is generally bad practice. It does not scale well, and opens you up for many different types of errors. Your back-end should be stateless, and there are a number of ways you could achieve that, for example storing the records in a separate table in the DB, which only get finalised (and thus moved into the "real" tables) at the end of the several screens you have.

In direct answer to your questions, without opening a can of worms

A) There is pretty much no worse way to implement data capture
B) Setting variables to null in .NET does not clear down memory.
C) Yes, yes you do. By definition every user is sharing the same static data.

I would keep your service delcarations local, and only use global variables for the constants. You're not saving much by declaring them globally. Also, I would use a const string instead of a static string.

I think the others have answered your questions. My suggestion to help fix your code would be to do some of the following:

  1. m_PersonID should not be static - keep it an instance property/field of the page and have it as static. In fact, class-level variables in code behind can lend itself to fairly unreadable code very quickly. Does it really need to be class-level, or can it be defined in the method where you need it (and just, perhaps, passed as an argument to other methods)?
  2. m_ServiceResult - same for this. Not sure why you have it, and it doesn't need to be static. Try to move it to a method-level variable.
  3. m_SortExpression could just be a const
  4. m_Service - again, I don't see the need for this to be a static. If it's just a proxy to a service, I don't think you need to keep it in memory to avoid unnecessary overhead. I think they problems keeping it static far outweigh the small overhead of having the service client be a method-level variable.
  5. In regards to the static dataset, you may want to consider caching the large result set, if the data is fairly static for the user. Or, really take a look at what you're returning and evaluate if you really need all that data. If you're performing calculations in the code-behind, that's probably not the best place for it. Consider your service layer as the place for those calculations (or the db if you have a lot of your logic in stored procs - not saying that's the place for it, but just acknowledging that it's a possibility).
  6. Also, a dataset is pretty large and bulky. Do you need this structure, or is a set of streamlined entity objects more appropriate? This item pretty much goes with #5, since you really should evaluate how you're retrieving data, storing it and acting upon it. A dataset may be the quick and dirty answer, but usually it's not the efficient answer.

In short, dump the statics and move to private, method-level variables where possible. Try to reduce the amount of data you have coming back from the database. Consider methods that take parameters instead of using class-level and/or global variables.

I hope this helps. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM