We have an asp.net forms based Order system. The user starts at Orders_Create form and then each step in the process (enter billing info, select products, shipping choices, etc..) is a seperate .aspx page. As we step through we're loading all of the data into a CSLA businessbase Order object. At the very end we call mObject.Save() and all of the data from the object is saved into the various Order tables in SQL.
We're trying to do two things. 1 is to persist this object form form to form. So in the start form I want to initialize myOrder object and load the creation date and userID. Then I want to pass that object to the bill to form, load the billing information. Then pass the object to the products form and fill the product child collection etc.. Then in the final form where it says Create Order we save it to SQL. I don't want to hit the sql database writing out partial orders on each load and unload like we're doing now What is the best practice for persisting this object from page to page? I could chuck it in the session variable but i'm worried about multiple browsers being open and someone working two orders at once?
Second, if the user closes their browser or they crash or whatever else, I would like to save their state. I'm not sure if I should serialize the object and stash the xml somewhere? Maybe I should write something in the Session_End that serializes the object and writes it to an SQL table or their user system folder as an .xml file. Then when I load next time i check for an abandoned session object? What is the best practice for that? thanks
I just can't decide. I am leaning towards dumping object into a session variable on each Next_Click of each page and then in the page load re-loading object. Also creating a session_end event that will save the data out to the dbase in case they crash or close browser, then check for it the next time they load the page.
I'm concerned about performance. We're anticipating quite a few concurrent users and we already have hour long sessions in our app.
I was also considering a Multi-view asp.net control but i'm afraid the viewstate is going to get huge and it has a large initial load time to pull all the controls of all the pages down.
The last idea was to serialize the object between each step in the wizard and storing the data in a temporary record in our SQL dbase. Then on the next page we deserialize and load the objects up in the page_load. This keeps the memory free but requires this large object round trip at each step of the wizard. Is there a good alternative I'm missing.
I just can't decide where to pay the performance price. Session variable, dbase roundtrips, large viewstate...
From personal experience, I would consider Session as a last resort. Session can't really be considered durable in any form - aside from session timeouts, it can die on an app-pool recycle, which happens an awful lot more often than you might think. Also, I have found that Session_End is less than reliable in ASP.NET, even in the InProc mode (whic the VS docs say is the only officialy supported session scenario where Session_End even has a chance to fire.)
I wouldn't consider ViewState either, for exactly the reasons you mentioned.
To my mind, if you need anything even remotely reliable, you will need to implement something more durable. Moving your session state to a state server/state database should be relatively simple, and would probably be the "least pain" for your existing codebase. Other than that, you're looking at developing some of your own code to persist what you need. From a performance perspective, I wouldn't think writing your "session state" to a database would be a terribly expensive operation, unless your object graph is really ungainly. I know you say "large object", but how large is large? And honestly, you may be prematurely optimizing - you don't really know what writing your object graph to a database is going to take until you try it.
I recommend to never use InProc sessions for real apps. I have used a State Server to handle sessions in a web farm. It is a pretty good solution and you avoid the appdomain recycle problem for InProc.
I had a large web app where we used session variables and passed them from form to form exactly as you described. The only thing to add is that once you save the order then simply clear the session variable to reduce memory usage. It will also speed up all the other pages that user goes to as their session state is no longer as large on each page access.
And now that Windows Server AppFabric is almost here (RC is available and requires WS 2008 R2) you will soon have AppFabric Caching Services (formerly project "Velocity") for high-speed access, scale, and high availability to application data.
"The first release of Windows Server AppFabric has two parts:
Look at the white paper from David Chappel available on MSDN: Introducing Windows Server AppFabric.
Copyright (c) Marimer LLC