ASP.NET Passing Data Between Multiple Pages Session - asp.net

So there seems not be any pretty answer to the question of how pass data between multiple pages. After having done a little homework here's why (or at least what I've gleaned):
ViewState variables don't persist across pages.
Session variables are volatile and must be used sparingly.
Cookies have potential safety issues and take time and must be kept small.
Storing vars in the URL has limits to the amount of data and can be unsafe.
Storing vars temporarily in a db is a real pita because you add one table per object that might be potentially passed to another page.
So far it is looking like I will be using hidden fields to pass a keyid and unique id to the next page and then retrieve the data from the db. What are your thoughts on all of this? What is the best way to go about doing any of it? I am early in the development of this app, so making changes now is preferred.
edit: I am anticipating a lot of users using this application at any one time, does that affect whether or not I should be using SQL Server based Session?

If you want to persist state, yes store it in the database since you don't have to worry about an expiration. The Session is similar except you have to worry about the Session expiring. In both cases concurrent calls that write similar data to the same area could cause problems and need to be accounted for.
Session is good when you don't have to worry about multiple web servers or timeout issues. The database gives you more scalability but at a cost of doing lots of db read/writes and you have to consider clean up.
Personally I would try to use the following decision tree:
Is the data simple, short and not private -> query string
Is the data less simple but only needs to exist for a short time -> session
Will the data be needed across multiple area and be persistent for long period of time -> database
Of course there is more to it that this but that should give you a basic outline of considerations since you are just starting out. Keep it simple. Don't try to over engineer a solution if a simple query string will suffice. You can always over engineer late as long as you have kept it simple to start.

I think context is important here, e.g. what are you trying to pass between pages and why?
If you are dealing with complex, multi-part forms, then you can implement the form in a single page, simply showing or hiding relevant element. Use usercontrols and custom controls as much as possible to facilitate isolation and reusability. This makes life a lot easier across the board.
Anything that is user-generated is almost certainly going to end up in a database anyway - so #5 does not seem relevant. That is you shouldn't have to store data "temporarily" in a database- what data would need to be persisted between pages that isn't part of your application.
Anything else would seem to be session related and not that much data.
I could add some more thoughts if I knew what specifically you were dealing with.
Oh - "cookies have potential safety issues and take time" - you're going to use cookies, unless you don't want to be able to identify return visitors. Any potential safety issues would only be a result of bad implementation, and certainly passing data in hidden fields is no better. And you really don't want to get into writing an ASP.NET app that is designed around pages posting to forms other than itself. That's just a headache for many reasons and I can't think of a benefit of doing this as part of basic application design.

Session variables should work fine for your needs.
I would go with StateServer or SQLServer Session state mode. Using mode InProc is the fastest, but it has some issues (including all user sessions getting dropped when a new binary is pushed, web.config changes, etc). Sessions are volatile, but you can control the volatility in several ways. Sessions require cookies unless they are configured as cookieless (which I highly recommend you stay away from), but I think that is a reasonable requirement.
Also, you can create a struct or serializable class from which you create objects that you can store in a session variable. The struct or class will allow you to keep all of your data in one place - you only have one session variable to worry about.
There is going to be advantages and disadvantages for any method, it's all about finding the best method. I hope this helps.

All methods have their pros and cons. It would all depend on the scenario you are working in.
Session variables work quite well if used within reason. InProc sessions in traffic heavy sites can quickly drain your resources but you can always switch to SQL Server based session that does most of the DB work for you.

Related

Should I avoid the session with a complex object in asp.net?

Here's my issue, we have a large patient object that is used on multiple screens throughout the admin. Each screen contains different information about the same patient. It can't all be on one screen.
The only time I want to persist the patient is when the user clicks save. I need to have an in memory patient somewhere. A user may be in the admin, change patient information on various screens, run validation and decide to not save that patient. This is typical use.
Is it ok to store this patient in the session? Or, is there a better approach to do this? At most this admin would have 20 users with access.
Opinions may vary on this. Session is tricky, especially if you use something other than in-memory session. Distributed session will break a non-serializable object. If this object is a simple POCO or object you control, try your best to make it play with serialization. If it does you're set. For an admin tool without much load I'd say you'd be fine.
Hey I found this - know nothing about the site, but illustrates my point:
https://www.fortify.com/vulncat/en/vulncat/dotnet/asp_dotnet_bad_practices_non_serializable_object_stored_in_session.html
I had a similar situation with similar amount of users. I did it and it worked great.
My situation was about scheduling events.
Someone would create an event and through multiple web pages would modify and configure this event. When they were all done it would save all the details to SQL. In the end, I was surprised just how well it worked.
Session should be fine here. You have what appears to be a light user load... but you might want to check exactly how much memory the object takes up, multiply that by the maximum number of users, and see where you are.
If you want to avoid the session altogether, you could use System.Web.Caching to store the object instead, and key the stored object using the users identifier plus some constant string.
In either case, you'll want to be aware of how many web servers are running the application. If it's just one web server, no worries. If you have multiple web servers, you'll want to make sure they are "sticky" - then the user is guaranteed to have all requests processed by the same server. How this is done is entirely dependent on your flavor of load balancing... normally the "IT folks" handle this for you.

is it ok to store rather big amount of data in session?

I'm doing a survey builder, and I think to store the survey in session with a unique guid key until the user creates it fully and saves it I'm thinking it is going to be an array of 100~200 objects (8 properties class)
That sounds like a fair use of Session.
Whether your data is too large depends on quite a few things, such as your web server's memory. The best thing to do is test the performance using Session. If you find your data is too heavy for Session have a look at ASP.NET Profile.
That doesn't sound like that much data unless we are talking about reams of text for each answer. I would not worry about it unless I was working on a web site expected to have thousands of these open at any given point in time.
IMHO I think the data should be stored in something other than the Session.
Session objects can disappear for a myriad of reasons. Would your users be annoyed if their answers are not persisted and needs to start afresh.
Remember to write the data to a persistent store (DB, files, etc) as soon as possible unless the users don't mind starting over.
I agree with ggonsalv. I would store the data somewhere just in case the session is lost. I have been to sites where I fill stuff out and then it looses it near the end. It's not fun to start over.

Is there any other way to store data in web application

We use ViewState to store data that is being edited by users. However, ViewState just got too large so we really want something that is faster.
We considered session, but it has to be manually collected when users travel among pages.
Does anybody has suggestions?
Update:
Actually I am using Asp.net. They reason we do not want to use session is:
1. We don't need to carry our data among pages.
2. When developer put something into session, he has to remember to delete it if it is no longer useful. Otherwise, the session will get bigger and bigger. This is kind of trival.
You say you want the data stored server side and its should be automatically available?
You could trick the viewstate into storing its data in session rather than a hidden field by using this technique:
http://aspadvice.com/blogs/robertb/archive/2005/11/16/13835.aspx
You might find this article interesting as well which shows another technique to store your viewstate server side:
http://msdn.microsoft.com/en-us/magazine/cc188774.aspx#S6
Despite the initial complexity of getting this set up I think it would be the best solution because then you don't have to change your code throughout, it can still use ViewState as normal without realising this is now saved on the server.
You can look into Conversations.
http://evolutionarygoo.com/blog/?p=68
http://code.google.com/p/google-guice/issues/detail?id=5
You can use the database as a alternate to the session store. This would scale in terms of the size of the data stored, and if you use an appropriate caching strategy you can reduce the overhead of retrieving the data a great deal.

Where should IsChanged functionality be handled?

I'm having an internal debate about where I should handle checking for changes to data and can't decide on the practice that makes the most sense:
Handling IsChanged in the GUI - This requires persistence of data between page load and posting of data which is potentially a lot of bandwidth/page delivery overhead. This isn't so bad in a win forms application, but in a website, this could start having a major financial impact for bandwidth costs.
Handling it in the DAL - This requires multiple calls to the database to check if any data has changed prior to saving it. This potentially means an extra needless call to the database potentially causing scalability issues by needless database queries.
Handling it in a Save() stored proc - This would require the stored proc to potentially make an extra needless call to the table to check, but would save the extra call from the DAL to the database. This could potentially scale better than having the DAL handle it, but my gut says this can be done better.
Handling it in a trigger - This would require using a trigger (which I'm emotionally averse to, I tend to avoid triggers except where absolutely necessary).
Don't handle IsChanged functionality at all - It not only becomes hard to handle the "LastUpdated" date, but saving data unnecessarily to the database seems like a bad practice for scalability in itself.
So each approach has its drawbacks and I'm at a loss as to which is the best of this bad bunch. Does anyone have any more scalable ideas for handling data persistence for the specific purpose of seeing if anything has changed?
Architecture: SQL Server 2005, ASP.NET MVC, IIS7, High scalability requirements for non-specific global audience.
Okay, here's another solution - I've not thought through all the repercussions, but it could work I think:
Think about the GetHashCode() comparison functionality:
At page load time, you calculate the hash code for your page data. You store the hashcode in the page data or viewstate/session if that's what you prefer.
At data post (postback) you calculate the hash code of the data that was posted and compare it to the original hash. If it's different, the user changed something and you can save it back to the database.
Pros
You don't have to store all your original data in the page load which cuts down on bandwidth/page delivery overhead.
You don't have to have your DAL do multiple calls to the database to determine if something's changed.
The record will only be updated in the database if something's changed and hence maintain your correct LastUpdated date.
Cons
You still have to load any original data from the database into your business object that wasn't stored in the "viewstate" that is necessary to save a valid record to your database.
Change of one field will change the hash, but you don't know which field unless you call the original data from the database to compare. On a side note, perhaps you don't need to. If you've gotta update any of the fields the timestamp changes and overwriting a field that hasn't changed for all intensive purposes doesn't have any effect.
You can't completely rule out the chance of collisions but they would be rare. This comes down to is the repercussion of a collision acceptable or not?
Either/Or
If you store the hash in the session, then that saves bandwidth, but increases server resources so you have a potential scalability issue in either case to consider.
Unknowns
Is the overhead of updating a single column and different than that of updating multiple/all columns in a record? I don't know what that performance overhead is.
I handle it in the DAL - it has the original values in it so no need to go to the database.
For each entity in your system introduce additional Version field. With this field you will be able to check for changes at the database level.
Since you have a web application and usually scalability matters for web application, I would suggest you to avoid IsChanged logic at the UI level. LastUpdated date can be set at the database level during Save operation.

Keeping data in session vs. populate on postback

What is preferable, keeping a dataset in session or filling the dataset on each postback?
That would depend on many factors. It is usually best not to keep too many items in session memory if your session is inproc or on a state server because it is less scalable.
If your session resides on the database, it might be better to just requery and repopulate the dataset unless the query is costly to execute.
Don't use the session!!! If the user opens a second tab with a different request the session will be reused and the results will not be the ones that he/she expects. You can use a combination of ViewState and Session but still measure how much you can handle without any sort of caching before you resort to caching.
It depends how heavily you will do that and where your session data is stored on the server.
Keeping the datasets in session surely affects memory usage. All of the session variables are stored in memory, or in SQL server if you use SQL Server state. You can also offload the load to a different machine using the State Server mode.
The serialization/deserialization aspect. If you use insanely large datasets it could influence server seide performance badly.
On the other hand having very large viewstates on pages can be a real performance killer. So I would keep datasets in session or in the cache and look for an "outproc" way to store that session data.
Since I want as few database operations as possible, I will keep the data in session, but I'm not sure what would be the best way to do it. How do I handle concurrency and also since the data is shared when two users simultaneously use the page how can I make sure each of them have their own set of data in the session?
I usually keep it in session if it is not too big and/or the db is far and slow. If the data is big, in general, it's better to reload.
Sometimes I use the Cache, I load from Db the first time and put it in the cache. During postback I check the chache and if it is empty I reload.
So the server manage the cache by itself.
the trouble with the session is that if it's in proc it could disappear which isn't great, if it's state server then you have to serialize and if it's sql sate your're doing a round trip anyway!
if the result set is large do custom paging so that you are only returning a small subset of the total results.
then if you think more than one user will see this result set put each page in the cache as the user pages making sure that the cache is renewed when the data changes or after a while of it not being accessed.
if you don't want to make many round trips and you think you've got the memory then bung the whole dataset in the cache but be careful it doesn't melt the web server.
using the cache means users don't need their own set of data rather they use the global set.
as far as concurrency goes when you load up the insert/ edit page you need to populate it with fresh data and renew the cache after the add/update.
I'm a big believer in decoupling and i rarely, if ever, see the need to throw a full dataset out to the user interface.
You should really only pass objects to the UI which needs to be used so unless you're showing a big diagram or some sort of data structure which needs to display relationships between data it's not worth the cost.
Smaller subsets of data, when applicable, is far more efficient. Is your application actually using all features within a dataset on the UI? if not, then the best way to proceed would be to only pass the data out that you're displaying.
If you're binding data to a control and sorting/paging etc through it, you can implement a lot of the interfaces which enables the dataset to support this, in a lot smaller piece of code.
On that note, i'd keep data, which is largely static (e.g. it doesn't update that often) in the cache. So you need to look at how often the data is updated before you can really make a decision for this.
Lastly, i'll say this again, i see the need to utilise a dataset in the UI very, very rarely..it's a very heavy data object and the cost benefits of looking at your data requirements, versus ease of implementation, could far outweigh the need to cache a dataset.
IMHO, datasets are rather bad to use if you're worried about performance or memory utilisation.
Your answer doesn't hint at the use of the data. Is it reference data? Is the user actively updating it? Is more than one user meant to have update access at any one time?
Without any better information than you provided, go with the accepted wisdom that says keeping large amounts of data in session is a way to guarantee that your application will not scale and will require hefty resources to serve a handful of people.
There's are usually better ways to manage large datasets without resorting to loading all the data in-memory.
Failing that, if your application data needs are truly monsterous, then consider a heavy client with a web service back-end. It may be better suited than making a web page.
As other answers have noted, the answer "depends". However I will assume that you are talking about data that is shared between users. In that case you should not store the dataset in the user's session, but repopulate on postback.
In addition, you should populate a cache near the data access layer of your application to increase interactive performance and reduce load on the database. The design of your cache will again depend on the type of data (read-only vs. read/write vs. read-mostly).
This approach decouples the user session (a UI-layer concept) from data management, and provides the added benefit of supporting shared use of cached data (in cases where data is common across users).
Neither--don't "keep" anything! Display only what a user needs to see and build an efficient paging scheme to see rows backwards or fowards.
rp
Keep in session. Have option to repopulate if you need to, for example if the session memory is wiped.

Resources