Working with Large JSON stored in client side Hidden - asp.net

I am working on a page which has 3 jQGrids and i use JSON to bind it. Working on MVC 3 application.
Example, i have a dropdown that shows Department Name list, if i change any department i need to load all the employees under that department in my grid. User edit some records in a grid often.
But the user will never save immediately, they keep editing so many
department employees and do a single save.
To persist all the changes till user click global save, i decided to keep all the employee record details in a JSOn format stored in a hidden field. So i load from hidden and bind to grid based on selected department and update local JSON when user update in grid and finally i send the hidden JSON to server.
I am storing 10 fields of 100 employee details JSON data in hidden field and use. I know i am increasing response size and post data
size. Question is, will it impact a big problem in performace? or can
i store in a session and load from it? Which would be the best way?

Theoretically there is no other problem than the delay that a page make to send back the data when the user make post back.
But in real life I have see (rare but existing ones) problems with very big fields on post back. Some routers, or proxy they cuts them, or block them - I do not know the actually reason, some times they maybe just stupid filters.
To avoid this rare case from happening you can compress and split the input hidden field to more than ones (the issues appears when the size is huge on one).
Now, the session is a good solution that can help to minimize the data send front and back. Its may grow up the session, and you must find a way what and how you handle if the user opens two same windows, the session data must be two different ones.
Some examples on how you can compress the input field. Is talking about viewstate, but the idea is the same:
http://www.codeproject.com/Articles/14733/ViewState-Compression
http://www.hanselman.com/blog/ZippingCompressingViewStateInASPNET.aspx
http://www.bloggingdeveloper.com/post/How-To-Compress-ViewState-in-ASPNET-20-ViewState-Compression-with-SystemIOCompression.aspx

Related

ASP.Net - Persistent shopping cart across sessions

What would be considered best practice for implementing a persistent shopping cart in an ASP.net Web Forms(*) based application? The only built-in way seems to be involving the Session state, which is not ideal because once you close the browser... it's gone. One way seems to be involving the localStorage via Javascript, but that creates awkward client/server mixups, as the data processing is meant to be done server side.
(* please pay attention to that part - MVC or Blazor based solutions will not work for this particular case)
Well, I can't imagine any practical application that involves database operations having ANY kind of suggesting that some kind of session, or view state will have ANY kind of relevance to database operations?
Be it a person filling out an invoice, or making orders or anything?
Not at all different then if you were writing a desktop application.
If a user is building up a list of items or "things" for/in an order?
Then as they build up such an order, then a database "order" record and structure will be built up. No different than say even building an invoice system say for the desktop with ms-access.
The only "use" of say session in most cases allows you to pass information from one page to another. (In place of say using parameters in the URL).
So, person might have a shopping basket of items (in your database, right!!!!).
They browse/search for more things to add to that shopping cart.
So say while on some items page, they choose to buy/select. When they make that choice, then you might say shove the ProductID into session, and then jump back into the current basket of items page, check session for a new product, and then insert/add that new item to the basket (which was being saved in the database).
If they log off, then fine. When they log back on, then you can load the current basket of items for display, and then allow them to continue shopping.
the only thing you going to use session for (or viewstate) is to allow the person to jump around looking at items, and then upon selection, you get/grab that particular product ID into session, jump back to the basket page, and add this new item from session, and then display their list of selected items.
So, in your database you have their current active order/basket, and thus when the user logs on, you can jump to that most recent or only "active order" page, and pull that order from the database. And then display all the details etc.
No session or viewstate would be required nor used at that point in time.
Not really any different than building up a invoice in a accounting package, then closing the program, and then next day, you launch the accounting package, load up the invoice, and thus can continue working on that invoice until you are done.
So, they look at the order, and go, "hum", I want to browse some more. So, they go look at/buy/choose/select another product. When they do, then you can now jump back to the current orders/basket page, and check session for the value just passed, add to order/basket, and now display the items in the basket, and that one "product id" in session can be pulled out, and is no longer required.
so session is not some kind of "magic" database system but is really only a feature to allow you to persist some values for a very short time, and only a simple "id" or simple variable in code for a rather short time. So session is ideal for passing a few values for use in code behind variables from one page to another.
Thus things like an address, name, products selected? That goes in the database, and not session.
For the most part, such software really not much different then desktop software.
You save and build up the list of items attached to a given order, and that order going to exist in the database.
So no real development approach here suggests saving their name, billing address, their past orders, the current new basket/order they have? That all going to be saved in a database.
So, session() is only relevant in most cases to "pass" some values, or "hold" some values for code behind.
So, if they select some product from a grid, you would shove productID into session, jump to the basket, add the new item in code behind to that order, and then let the page pull the information from the database to display items in that order.
So "session" persisting of data? That really only for a few variables that your code might need for some data operations, but your data for that order is not persisted in session - it goes into the database.
Session has VERY little to do with using a database system to "manage" and "hold" and "have" the order saved in the database system.
Session is not some kind of database - only a "active" storage of some variables you might need during program operation.
Easy, store it in database for logged in user.
use local storage or cookies for guess.

Viewstate or Session or Database Call

I have a this asp.net page which upon first time load:
1: Make a DB call and get data - XML string (this chunk can go beyond 100kb). And this DB call is a bit expensive takes about 5-10 secs.
2: I loop through this XML and create a Custom Collection with values from XML. Then Bind it to a Repeater Control.
Now the repeater control has one text input. User is free to enter values in one or more or all TBs or leave all blank. Then then hit Save button.
On Save Postback, I will have to loop through all rows in the Repeater, Collect all the rows that has some input in the and generate an XML using the initial values and this new input value and Save it to DB.
Problem:
So I will need reference to all the initial XML values. I can think of these options and looking for inputs on selecting a best one.
1: ViewState: Store my Collection or XML string in ViewState - I'm sure it is will be too huge
2: Session: Use Session to store Collection of xml string - Again
3: DB Call: Make a DB call to get the data again - as I said it is kind of expensive call and my DBA is asking me to avoid this
4: HiddenField: Store the essential data from XML in to HiddenField and use that for Save manipulation. i.e. in each repeater item find all the hiddenfields
Which one is best in terms of better request response and less resource utilization on server?
Or is there a better way I am missing?
PS: Have to use ASP.NET 2.0 WebForms only.
Update1:
I tried the following with ViewState:
1: Store entire xml string: ViewState length = 97484 and FireBug shows pagesize - 162Kb
2:Store stripped down version of Collection with required only data: ViewState length = 27372 and FireBug shows pagesize - 94Kb and with gzip compression it reduces to 13kb.
With the existing website FireBug shows Size 236Kb.
So definitely option 2 is better and my new version is better then current website.
So any inputs?
A quick question - who is your target audience for this page? If it's an internal website for a company then just storing the data in viewstate might be acceptable. If it's for external people, e.g. potential customers, then speed and performance probably matter to you more.
Viewstate - have you tried adding your XML to viewstate? How much did it increase the page size by? If you're gzipping all of your pages rather than sending them over the wire uncompressed then you could see about a 70% reduction in size - 30kb isn't that much these days...
Session - it is worth remembering that the server can and will drop data from sessions if it runs out of space. They can also expire. Do you trust your users not to log in again in a new tab and then submit the page that they've had open for the last 10 hours? While using session results in less data on the wire you might need to re-pull the data from the db if the value does end up being dropped for whatever reason. Also, if you're in a web farm environment etc there are complications involving synchronizing sessions across servers.
DB Call - can the query be optimised in any way? Are the indices on all the fields that need them? Maybe you and your DBA can make it less painful to pull. But then again, if the data can change between you pulling it the first time and the user submitting their changes then you wouldn't want to re-pull it, I suspect.
Hidden Fields - With these you'd be saving less data than if you put the whole string in Viewstate. The page wouldn't be depending on the state of the webserver like with session and nor would you be racing against other users changing the state of the db.
On the whole, I think 4 is probably the best bet if you can afford to slow your pages down a little. Use Firebug/YSlow and compare how much data is transmitted before and after implementing 4.
One final thought - how are things like this persisted between postbacks in the rest of your webapp? Assuming that you haven't written the whole thing on your own/only just started it you might be able to find some clues as to how other developers in a similar situation solved the problem.
Edit:
there is a load-balancer, not sure how it will play with Session
If you have a load balancer then you need to make sure that session state is stored in a state server or similar and not in the process ("inproc"). If the session is stored on the webserver then option 2 will play very badly with the load balancer.
While I'm not a huge fan of overusing session, this will probably be your best bet as it will be your fastest option from the user's standpoint.
Since session state does have it's own inherit issues, you could load the data you need into session, and if your session drops for whatever reason, just do another database hit and reload it.
I would really stay away from options 1 and 4 just because of the amount of unnecessary data you will be sending to the client, and potentially slowing down their experience.
Option 3 will also slow down the user experience, so I would stay away from that if at all possible unless you can speed up your query time.

very large viewstate breaking web app

I have a web app, that consumes a web service. The main page runs a search - by passing parameters to a particular web service method, and I bind the results to a gridview.
I have implemented sorting and paging on the grid. By putting the datatable that the grid is bound to in the viewstate and then reading / sorting / filtering it as necessary - and rebinding to the grid.
As the amount of data coming back from the web service has increased dramatically, when I try to page/sort etc I receive the following errors.
The connection was reset
The connection to the server was reset while the page was loading.
I have searched around a bit, and it seems that a very large viewstate is to blame for this.
But surely the only other option is to
Limit the results
Stick the datatable in the session rather than the viewstate
Something else I am unaware of
Previously I did have the datatable in the session, as some of this data needed to persist from page to page - (not being posted however so viewstate was not an option). As the amount of data rose and the necessity to persist it was removed, I used the viewstate instead. Thinking this was a better option than the session because of the amount of data the session would have to hold and the number of users using the app.
It appears maybe not.
I thought that when the viewstate got very big, that .net split it over more than one hidden viewstate field, but it seems all I'm getting is one mammoth viewstate that I have trouble viewing in the source.
Can anyone enlighten me as to how to avoid the error I'm getting? If it is indeed to do with the amount of data in the viewstate?
It sounds like your caching the whole dataset for all pages even though you are only presenting one page of that data. I would change your pagination to only require the data for the current page the user is on.
If the query is heavy and you don't want to have to be constantly calling it over and over because there is a lot of paging back and forth (you should test typical useage pattern) then I would implement some type of caching on the web service end to cache page by page (by specific user if the data is specific to a user) and have it expire rather quick (eg a few minuites).
I think you need to limit the total amount of data your dealing with. Change your code to not pass back extra data that might never be needed is a good place to start.
EDIT: Based on your comments:
You can't change the web service
The user can manipulate the query by filtering or sorting
There is a large amount of data returned by the web service
The data is user specific
Well I think you have a perfect case for using the Session then. This can be taxing the the server with large amounts of users and data so you might want to implement some logic to clear the data from the Session and not wait for it to expire (like on certain landing pages you know the user will go when they are done, clear the session data).
You really want to get it out of the ViewState beacuse it is a huge bandwidth hog. Just look at your physical page size and that data is being passed back and forth with every action. Moving it to the Session would eliminate that bandwidth useage and allow for you to do everything you need.
You could also look at the data the web service is bringing back and store it in a custom object that you make as 'thin' as possible. If your storing a DataSet or a DataTable in your Session, those objects have some extra overhead you probably don't need so store the data as an array of some custom thin object and just bind to that. You would need to map the result from the WS to your custom object but this is a good option you cut down on memory useage.
Let me know if there is something else I am missing.
I wouldn't put the data in either the view state or the session. Instead store the bare minimum information to re-request the dataset from the web service and store that (in either view state or session, or even on the URL). Then call the web service using that data and reaction the data on each request. If necessary, look to use some form of caching (memCache) to improve performance.

Why are hidden fields used?

I have always seen a lot of hidden fields used in web applications. I have worked with code which is written to use a lot of hidden fields and the data values from the visible fields sent back and forth to them. Though I fail to understand why the hidden fields are used. I can almost always think of ways to resolve the same problem without the use of hidden fields. How do hidden fields help in design?
Can anyone tell me what exactly is the advantage that hidden fields provide? Why are hidden fields used?
Hidden fields is just the easiest way, that is why they are used quite a bit.
Alternatives:
storing data in a session server-side (with sessionid cookie)
storing data in a transaction server-side (with transaction id as the single hidden field)
using URL path instead of hidden field query parameters where applicable
Main concerns:
the value of the hidden field cannot be trusted to not be tampered with from page to page (as opposed to server-side storage)
big data needs to be posted every time, could be a problem, and is not possible for some data (for example uploaded images)
Main advantages:
no sticky sessions that spill between pages and multiple browser windows
no server-side cleanup necessary (for expired data)
accessible to client-side scripts
Suppose you want to edit an object. Now it's helpful to put the ID into a hidden field. Of course, you must never rely on that value (i.e. make sure the user has appropriate rights upon insert/update).
Still, this is a very convenient solution. Showing the ID in a visible field (e.g. read-only text box) is possible, but irritating to the user.
Storing the ID in a session / cookie is prohibitive, because it disallows multiple opened edit windows at the same time and imposes lifetime restrictions (session timeout leads to a broken edit operation, very annoying).
Using the URL is possible, but breaks design rules, i.e. use POST when modifying data. Also, since it is visible to the user it creates uglier URLs.
Most typical use I see/use is for IDs and other things that really don't need to be on the page for any other reason than its needed at some point to be sent back to the server.
-edit, should've included more detail-
say for instance you have some object you want to update -- the UI sends back a collection of values and the server at that point may or may not know "hey this is a customer object" so you fire off a request to the server and say "hey, give me ID 7" and now you have your customer object as the system knows it. The updates are applied, validated, whatever and now your UI gets the completed result.
I guess a good excuse/argument is using linq. Try to update an object in linq without getting it from the DB first. It has no real idea that it's something it can keep track of until you get the full object.
heres one reason, convenient way of passing data between client code (javascript) and server side.
There are many useful scenarios.
One is to "store" some data on a page which should not be entered by a user. For example, store the user ID when generate a page, then this value will be auto-submitted with the form back to the server.
One other scenario is security. Add some hidden token to the page and check its existence on the server. This will help identify whether a form was submitted via the browser or by some bot which just posted to some url on your site.
It keeps things out of the URL (as in the querystring) so it keeps that clean. It also keeps things out of Session that may not necessarily need to be in there.
Other than that, I can't think of too many other benefits.
They are generally used to store state as an interaction progresses. Cookies could be used instead, but some people disable them. Could also use a single hidden field to point at server-side state, but then there are session-stickiness issues.
If you are using hidden field in the form, you are increasing the burden of form by including a new control.
If there is no need to take hidden field, you should't take it because it is not suitable on the bases of security point. using hidden field does not come under the good programming. Because it also affect the performance of application.

Storing IDs between pages for up to a day?

I need to store IDs (Contact IDs, Claim IDs, etc.) between multiple .aspx pages.
At the moment I am storing the ID in the Session and have set the Session timeout to 300 minutes. However, I am still getting errors because users are attempting to perform operations after the Session has expired.
I think users are leaving their web broswers open, locking their computers, going home for the evening, coming in the next morning and attempting to pick up where they left off.
I don't want to use the Querystring. Cookies are more for User IDs than Contact IDs and Claim IDs. Viewstate is only maintained per page. Persisting Session to a database seems unnecessarily complicated. I don't want to extend the Session timeout too much.
I'd ideally like them to be able to pick up where they left off in the morning.
What are the best practices for dealing with storing IDs between pages? How can I do this without them receiving a message saying their session has expired? Am I overlooking something obvious?!
I would put all this information into a database. This is classic use of a database, a means to store information needed for the application.
Cookies are bad because you have to assume they will be at the same PC from session to session. You have seem the problem with sessions.
If you do not want to use a database then you can use a file on the server. And read from that file.
You might actually find it much easier than complicated to create a sort of "landing pad" database where a user's item history is stored, or MRU list. I wouldn't tie it to their immediate session or cookie though. Let the session maintain the user state, let the database handle where they were when they went home or took that 7 hour lunch break.
As #David said this is a classic use of databases.
If you are in need of doing this without using databases, you can fall back on some of the "tricks" (read hacks) that are used in non-dynamic languages:
Create a hidden field which exists on every page, name the field appropriately for the data you are storing.
When you render the page create an XML fragment containing your ids and other data, encrypt it for display purposes (using base64 etc), place the value into the hidden field you created.
When the page is posted back, reverse #2 and recover your data, then apply the page changes.
Rinse and repeat. :)
Really this is not a very scalable solution, as the XML and base64 encoding will add 50% or more to your data size, and if there is significant data (100's of KB) this process can get out of control.
The last time I was asked to use this solution it was for moving a list of well defined data around with an application that did not always have access to the DB. It worked ok for the purposes, but was definitely not ideal.
You could go ahead and store the IDs in viewstate on the page, then on each page that requires that ID have a settable property for that page. Before redirecting to the page instantiate it and set the ID property.
You're correct, storing this type of data in session isn't really what it's meant for. Viewstate is a better mechanism for this.

Resources