How to store user entered values across a website using C#? - c#

I am currently working on a website that will have a high volume of traffic on it. The website has only 4-5 pages on it but I need to pass values selected on page 1 over to page 2 where more values are stored and so on until the user gets to page 5 where all values are passed to a third party system using XML.
Currently I use a dictionary object with roughly 20 keys stored in a single session object to hold the values across the different pages. I do this because some of the values are not just simple values like 'name' or 'age' values but can be complex like holding a dataset of results from an XML call on page 2.
I have read everywhere that global variables are bad so I am wondering if there is an alternative to using Sessions for this example? I cannot use a database to hold these values because of the way some of the values need to be stored (i.e. my variables are not just strings/ints). If I was to use global static variables how could I ensure the global variables are unique for each user?
Thanks for your thoughts.
Rich
** Edit 1 **
I am storing the current sessions in ASP.NET Session State and not inproc. I am just trying to figure out if what I am doing is bad practice or just generally accepted as an ok way of doing things. For example on the second page I get a XML result that I store as a dataset in my session for use on page 3/4 of my site. Should I be store/passing this info another way?

I cannot use a database to hold these
values because of the way some of the
values need to be stored (i.e. my
variables are not just strings/ints).
You actually can. You can serialise you object graph and store it as binary column in the database.
Additionally you can have this functionality out of the box and still using SessionState.
Here is an article on how to Store Session State in Sql Server.
So I would recommend to use Session but store the session state in the database.

Sessions are the right choice. The "global variables are bad" argument is a good one, but it's describing global variables, not session variables and pertains to how you organize data being passed among methods within your application. Storing data between pages can be done in only one of three ways:
Store the data in hidden fields or cookies (so everything gets passed back and forth for each page request). You could do this by just serializing your XML and other fancy data, but it sounds like a terrible idea.
Store the data in a database, flat file. This is a fine idea, but you'd still have to do the serializing work yourself.
Store the data in a session. This is exactly the same as option #2, except that C# is doing the serializing for you, and then saving the results in a flat file.
You do not have to do any work to separate the data of one user from another. Every visitor gets a unique session, and the data you store there won't ever be applied to another user (excluding a malicious attack such as a hijacked session).

I would think session is the appropriate place to put things that are relevant to your 'session'. It is true that over-using/abusing session can bite you with excessive memory consumption, but the alternatives can be a bit slower, just depending. Also, if you use SessionStateService or store the Session in SQL Server, you have slow-down in serializing/deserializing the session objects on each request.
You can use ViewState, but that means all of the data will get serialized to the HTTP Form, which means it will get passed back and forth on subsequent requests. Also, I think ViewState gets dropped from one ASP.NET form to the next, so unless you are on the same form, that won't work.
You can store the data in the database. One way is to have Session use SQL Server. If I were to use a database for this problem, I don't think I would use session in SQL Server though simply because if you store it yourself, then you could recover previously entered data.

Related

How are ViewStates accessible everywhere without being declared?

I was always under the impression that to access a variable in multiple methods, you'd either have to declare it as a class member or pass it in as an argument.
However, I was looking over some sample code recently to learn .NET, and I came across something called a ViewState. I understand it's meant to track some Pages and Control Properties, but I don't understand how it's being used here.
The code looks somewhat like this:
private void RowValidating(object sender, EventArg e) {
ViewState[Backup] = ViewState["TestId"];
// more code that does not include ViewStates
}
private void UpdateBox() {
// some code that does not include ViewStates
int box_id = ViewState[Backup];
// ...
}
How is ViewState accessible everywhere? It is not declared anywhere in the class or in any of the other class files, and this [Backup] key is just sort of created without initializing it. As far as I can tell, ViewState[Backup] does not exist until RowValidating is called.
Would it be possible to set ViewState as a global variable? Or could I always just make my own key that is accessible anywhere? It seems to behave like a dictionary, but I thought the notation was dict.Add(item, value), not dict[item] = value when working with a new item. It must be initialized somewhere, perhaps in some imported library?
Both Session() and ViewState are and can be used to persist values in your code. You don't have to declare them, they are built in features of asp.net
Session() is per user and thus is often used to persist values or even pass values between pages. However in some cases ViewState is preferable.
So for example if you have a productID or maybe even a house you are about to buy? Well, if you have two tabs open or even two different browsers open then Session() applies to all instances of the browser(s) in question open. So if a user has two seperate browsers opened, then the "ID" value you persist in session() will apply to both (so, be carefull, which house ID are you about to buy when you have 3 browser pages open to 3 differnt houses open? So session() is global to the user.
So for say "persisting" a row of data to pass to the next web page/form, Session() can be great - but keep in mind it is shared among all pages opened and in operation by that user. So session() is still per user - but global to that user.
Session() can be server "in memory" (the default). However, if you are using a server farm, then each of those multiple servers can't share their memory, and as such you have to adopt what is called SQL server based session. So in place of holding these values in memory, the session() state is shuffled from a serialized "blob" stored in SQL server. So if you hosting your site say on a cloud based system like Azure (as opposed to regular hosting), then session() can't persist on these so called "large services" based systems (or you are using a server farm with load balancing in which you have multiple-servers hosting the site for scalability reasons). Since multiple copies of the hosted web site can exist at the same time, then a means to have a common session() is required (so they shove a blob thing into SQL server). So you can still use session(), but it actually stored in sql server. It is noted that in some cases session() based on SQL server can cost performance. As high as 10% - perhaps a bit more. I find that in most cases you not notice this performance hit. But it works seamless() and in fact adopting SQL server based session will mean that session() is not frequent lost due to site execution errors. I had all kinds of issues with a site losing session(). If the web hosting and management system puts the server to sleep, or even .net code errors occur, it can (and will!!) often cause a application pool re-start - and that blows out session() (but not with SQL server based ones - they are rock solid).
ViewState is often preferred since it is by EACH NEW web page. And this is stored 100% in the browser. So to persist that houseID or product you about to purchase, then this occurs by page, and not all web pages in use by the user (so in this case, VieweState would be a far better choice). ViewState is thus stored by the browser and is much the SAME mechanisum used when you enter bunch of values in text boxes, and then do a post back. The web page travels up to server - page is processed and sent back down. But you will notice that MOST controls on the page retain their value. To achieve this then ViewState is used. And this applies to hidden text boxes (or hidden fields - much the same as a hidden text box). So this encrypted blob lives in the browser client side. And this blob thing thus goes along for the post-backs and round trips to keep those controls values in-tact.
So you can use session(), or ViewState But, as noted, you don't want to stuff too much into that ViewState, since it becomes part of that round trip life cycle. But ViewState as noted is often preferred since it is per page operation. However, since each new browser page opened creates a new local per page ViewState? Then ViewState can't as a general rule be used to pass values between web pages like Session() can.
However, you CAN pass all values of all controls to the next page. You can do this by using the post-back URL of a button. When you do this, then on FIRST page load, you can use the page.previous property in the on-load event. This will give you use of ALL values from the previous page - and you don't need Session() to do this. You can also use page.Previous if you do a server.TransferRequest as opposed to a Response.Redirect().
Last but not least? You see a lot of sites have a whole bunch of parameters in the URL. So this is often used and has a long history of use. Of course users can mess and change with these values - but they are still often used and often make the URL's rather ugly. For this reason I do like asp.net sites, since then URL's don't expose a bunch of stuff in the URL as parameters and keeps such information out of site and mind. You see a lot of shopping site still using parameters and values in the URL - and they do this for reasons of scalability - (they don't have to store the persisting values server side - it saves resources).

If we have more than 1 page to get details of users then how to handle user's data till last submit

I have 3 pages to get details of user and I'm confused what to do with users' temp data
whether
store in database and delete incomplete form data using scheduler
store in session for that user
store in cookies
All of the options you mention are valid in some cases.
I would not go for the cookies option since they are sent along with every request and the data could get too large.
If you want to keep information over sessions the database is your only option. Else wise choose the option you seem best.
It depends upon the requirement. The easiest will be session since clearing the data is not required .net will do it automatically on session-expire.
storing in database and cookie will result in more code. If you want to use the best option go for cookie it will use the least server resources, but the round trip can be costly if there are many cookies. since cookies also get transmitted every time u make a request.
The other options that you can think of is using the view state to persist the data. It will require the most code to accomplish, but will be the best since the data is only be kept till the user is completing the form. you will have to take one page data and pass it to another page in view state and so on.
1.if you use database then this option requires DB trips that is not good and it also effects to your application performance.
2.Session will be the best option to store user Temp data.With sessions you can use datatable object and then this datatable is assigned to session variable.
3.it creates a problem if some user disable browser's cookies.
Happy coding....

Store large amounts of data per session ASP.NET MVC

My MVC based application, hooks some web services which send back lots of data!
Using the same, I render my views. The web services are slow and out of my control.
So I would like to store this info per session, but I am afraid that, this will bring down my web server to its knees. With few hundred users, the web server will run out of memory.
Is there a way that I can store this session data in a file per session? I am more looking at some out of the box open source solutions.
I welcome, new suggestion as well!
You can store pretty much any object in the Session storage, with a few exceptions which are generally related to running on a server farm. I'm going to ignore those cases here however.
If you're dealing with only a few MB of data, storing it in the Session object (or a Cache, as #Rick suggests) isn't necessarily a major problem. Once the data has been returned from the web service and parsed into your own internal data structures, simply place the data structure's root object into the Session. I use this method fairly often to store the results of database queries that take a long time to run, especially when the query criteria are unlikely to change frequently.
For larger data sets you should probably use a database to store the information. Create tables that match the structure of the data you're returning and tag the data in some way to indicate how old it is and what criteria were used when fetching it. Update as required, and query the database for records on each client request.
There are plenty of other options, including creating temporary files to store the data using the SessionID to identify them, but I recommend investigating the database option first.
Caching is your friend. And since you use MS technology you might want to take a look at the Cache Class
You could just serialize the result collection and save it on files as xml (even process it using linq/XPath directly from XML) , or use any .net native xml database to store and persist data on a file.

Passing values between two "totally different" pages

To be clear, the two pages are only logically related in other words the values in my FirstPage.Aspx pass values to my SecondPage.Aspx so it control components and certain attributes of the controls in my SecondPage.Aspx, the SecondPage.Aspx is not a redirect or transfer from FirstPage.Asp. sorry am so sick of reading about all the answers but the one I actually need!
Consider the firstPage contains a textBox which get a value from the user or the web admin to set his preferences about the gridView page size on the SecondPage or a Text property of a label on the SecondPage
I want to explore my options to do so
PS: I was told to use a database to store values from the first page then on the page with my Label for example I connect to the database and retrieve the value and set it to the label...is this a best practice to let the page connect every time it loads to set some values sometimes it's just an int like 5, and most of the time I'd be connecting already to the database to display some table's data in a gridView or any databound control!
EDIT:
Sorry if I was a bit rude, it just hit me that I'm mainly getting the same answer that I read which is totally not my case!..and of course thanks to some of you mentioned the database solution, I hoped I could get an example or an article for my particular case since I think even it's simple but yet it's essential...
ASP.NET framework provides several mechanisms to maintain context that lasts across several HTTP requests. The data you want accessible across calls, can be stored in this context. All you have to do is decide how long do you want this context to be maintained (because it consumes resources), and if you want this context to be available across more than one server.
Application State : Which is maintained for the lifetime of the application i.e. from when the application is first loaded by ASP.NET, till it is unloaded for whatever reason.
Session State : ASP.NET is able to identify a series of HTTP requests emanating from a specific client (IP address), close to each other in time, as a session. It can create a session context that persists across such a session, in which you can store data that is accessible to the calls in the session. The session state can be made available across server boundaries by associating it with a DB or shared memory.
Database
Viewstate : You can use Viewstate to maintain context, but keep in mind that Viewstate is transferred over the wire for every request / response. It has been known to get quite large, specially if you use controls.
Cookies : Again, transferred on the wire for each request / response.
You can use:
Session variable
Cookie
Database value
each one of them have their own pros and cons
If you want the value to be stored the next time they come to page 2, use a database value. if not, use a session variable.
The database value will give you a persistent value, and you can then store other such user variables there.
the session will give persistent data, but only for the browsers current session. The data will be lost if their session times out.
From all you've stated, i would assume a database value.
U can use cookies, session etc but if you want to pass something that defines the whole content of the page, like an ID of some sort, you might just want to put it in the QueryString. (ex: default.aspx?id=4)
Cons: everyone can read (or change) the value, not usable for critical data
Pros: everyone can read the value, and the link can be sent to others
I'd suggest you start here: Get Started with ASP.NET
If I understand your question, you are looking to do Cross Page Posting. If one page isn't posting to a 2nd, you'll need to persist the data somehow (database, session, xml file, etc). But, from reading your question, you sound like you just want to cross page post...
Your question is very confusing, took me a lot of time before I could I understand what you actually need. Since there is no events in HTML, you will need to use JavaScript and some kind of web-service (AJAX).
Page A will store the value in database, and JavaScript on page B will constantly check database for new values, get them and output to the user. In order to that it needs to connect to some webservice/webmethod that will return the value from database to your page. A good example can be found here.
Alternatively you can refresh page every 5 seconds using
<meta HTTP-EQUIV="Refresh" content="5">
and check for the new database value on Page_Load server event.
I think the better answer is "Control State"
Reference : http://www.asp.net/general/videos/how-do-i-use-control-state-to-persist-information-for-a-custom-web-server-control
but I couldn't get this implemented on my case, two different pages
for example : the web user control is placed on News.aspx and the textbox which will have the value to be assigned to the control on News.aspx is placed in myAdmin.aspx page!
and to be honest, I didn't quite understand the code
So! do you think this is the best solution ? if yes do you think It can be used for my case (two different pages) ??

Storing xml data in a cookie

I'm trying to store an xml serialized object in a cookie, but i get an error like this:
A potentially dangerous Request.Cookies value was detected from the client (KundeContextCookie="<?xml version="1.0" ...")
I know the problem from similiar cases when you try to store something that looks like javascript code in a form input field.
What is the best practise here? Is there a way (like the form problem i described) to supress this warning from the asp.net framework, or should i JSON serialize instead or perhaps should i binary serialize it? What is common practise when storing serialized data in a cookie?
EDIT:
Thanks for the feedback. The reason i want to store more data in the cookie than the ID is because the object i really need takes about 2 seconds to retreive from a service i have no control over. I made a lightweight object 'KundeContext' to hold a few of the properties from the full object, but these are used 90% of the time. This way i only have to call the slow service on 10% of my pages. If i only stored the Id i would still have to call the service on almost all my pages.
I could store all the strings and ints seperately but the object has other lightweight objects like 'contactinformation' and 'address' that would be tedious to manually store for each of their properties.
Storing serialized data in a cookie is a very, very bad idea. Since users have complete control over cookie data, it's just too easy for them to use this mechanism to feed you malicious data. In other words: any weakness in your deserialization code becomes instantly exploitable (or at least a way to crash something).
Instead, only keep the simplest identifier possible in your cookies, of a type of which the format can easily be validated (for example, a GUID). Then, store your serialized data server-side (in a database, XML file on the filesystem, or whatever) and retrieve it using that identifier.
Edit: also, in this scenario, make sure that your identifier is random enough to make it infeasible for users to guess each other's identifiers, and impersonate each other by simply changing their own identifier a bit. Again, GUIDs (or ASP.NET session identifiers) work very well for this purpose.
Second edit after scenario clarification by question owner: why use your own cookies at all in this case? If you keep a reference to either the original object or your lightweight object in the session state (Session object), ASP.NET will take care of all implementation details for you in a pretty efficient way.
I wouldn't store data in XML in the cookie - there is a limit on cookie size for starters (used to be 4K for all headers including the cookie). Pick a less verbose encoding strategy such as delimiters instead e.g. a|b|c or separate cookie values. Delimited encoding makes it especially easy and fast to decode the values.
The error you see is ASP.NET complaining that the headers look like an XSS attack.
Look into the View State. Perhaps you'd like to persist the data across post-backs in the ViewState instead of using cookies. Otherwise, you should probably store the XML on the server and a unique identifier to that data in the cookie, instead.
You might look into using Session State to store the value. You can configure it to use a cookie to store the session id. This is also more secure, because the value is neither visible or changeable by the user-side.
Another alternative is to use a distributed caching mechanism to store the value. My current favorite is Memcached.

Categories