"State" management for asp.net mvc multi partial view + ajax app - asp.net-mvc

I am trying to convert my asp.net mvc4 app, which had fairly heavy use of SessionState, into a stateless app. I understand that I can store this information in the DB, and intend to do so.
My question, though, is about my particular architecture. My app has a main 'page' consisting of a number of partial view panels, which each have actions in them that can affect the other panels. What i've been doing up to now is storing the entire state of the viewModel (lots of inter-related EF list collections and 'record' objects) in the session, and its been working great. Except when the session just randomly dies.
So, I need to get this data out of the session, and into the DB where I can rebuild the thing at need. My concern is that, if I store the info in the database, every single action done on screen might affect 3-5 different panels, each with their own State updates, thats a minimum of 10 round trips to the DB for every interaction!
What are some strategies I can use to make this idea more scalable?
EXTRA INFO
The view in question here is a sort of POS shopping cart system. There are panels for selecting events, selecting/adding items to the cart, editing cart items, selecting contacts, editing contacts, displaying the cart items, displaying the cart 'subtotals', and finally, a panel with a [checkout] button.
Selecting a new event will change the list of available items. Selecting an item to add to the cart will change the cart item list, subtotals, as well as the checkout panel. Same for editing a cart item.
The main concern is how to recover from a lost session, as I've found the built-in asp.net session code too unreliable. My testers have encountered issues with sessions timing out, and then my app not having any kind of recovery process. When its installed on 1500 sites, each with an average of 10 users, its going to be a plague of lost session issues, and I need to combat that before it becomes a real problem.
I agree that I'm not going stateless...wrong choice of words used in a rush. I'm just trying to move that state into a form that I can rely on past the session failure. My main idea presently is to continue using the session as the local cache for the viewModel data, but to have a fallback operation that can rebuild the viewModel from DB if the session one is lost somehow.

You shouldn't necessarily be using a database to store (what sounds like) data that only needs to be persisted in the short term.
If these changes to the other partials are only relevant in the context of the current "master view," then I would suggest using jQuery AJAX to send off the requests, parse the response JSON and update the other views. Tutorials on jQuery AJAX and ASP.NET MVC are easy to find, if you don't already have the knowledge:
http://www.codeproject.com/Articles/41828/JQuery-AJAX-with-ASP-NET-MVC
This way, you don't need to make a bunch of round trips. If the changes need to be persisted beyond the context of the current view, make ONE round trip to the database to perform the update and then simply update all of the other partials from the in-memory response from the AJAX call.
You don't need to read from secondary storage multiple times when you already have all of the information you need in-memory. Just do the reading and writing once.

I decided to go with a hybrid approach. I'm still using session, but I'm building out a DB 'recovery' option, so that if the session portion is lost, the DB will be able to provide the values needed to rebuild the session seamlessly.
Seems to be working well, so far.

Related

How to ensure data consistency and truly take advantage of Core Data?

I've worked on several iOS apps, some of them utilize Core Data, and some of them don't. While I consider myself having a basic to somewhat good understanding of Core Data, there's always something that makes me doubt the usefulness of it. I've done a lot of reading on the subject, and the general consensus seems to be the advantages of using it outweighs the disadvantages. I recently submitted an app without using Core Data, and always planned on going back to update the project to utilize it when I have the time for some optimization work. Now's the time, but I wonder if it makes sense for the app I'm working on, and maybe I am not using it correctly all along. Please advise and point out what I am missing.
The project I am working on is a social networking app, which also has a front-end site. We have standard features like a newsfeed, event listing, the ability to follow/unfollow someone, and a map with POIs at user's location. Currently, we're using pagination whenever needed when requesting data from server.
My understanding of why Core Data is great:
Easier to manage data with complicated relationship
Easier to access data without having to pass them around
Easier to manipulate, fetch, and sort your data
Better memory utilization
Improve perceived performance by preloading data stored locally until latest data's received
The problem I am having is, since I am using pagination when requesting for data instead of requesting for all at once. The data stored locally is only a subset of the current state in the database. Let's use newsfeed as an example. If I do the following, it will cause some problems:
User manually refresh the newsfeed -> Controller notifies model that it needs the latest 20 items -> Model requests for the latest 20 items in the newsfeed and save them as NSManagedObject -> Model notifies controller that data is ready -> Fetch the latest 20 items to show in UITableView
If user A refreshes the newsfeed, background the app, and then user B deletes his post in the newsfeed (let's say it was 10th item) before user A foregrounds the app again to refresh the newsfeed. In user A's newsfeed, B's post will still be up there because according to the createdAt attribute, it's indeed one of the latest 20 items.
To fix this problem, I can think of a few solutions:
Add a flag to the item to indicate it's removed
Always discard local data when new data arrives
Disable pagination
Instead of using the workflow described above, always present the requested data only instead of fetching the latest
Solution 1 means custom code is required to deal with different clients since browser doesn't need deleted items but iOS client does. However, even though it can work, it can potentially mess up the pagination mechanism and can cause weird behaviours in the client. For example, if a large amount of items gets removed, the latest 20 items will contain only a few items that will actually show up in the newsfeed on the client when user refreshes it. As user follows more people, more stories will be inserted in his newsfeed as well. This solution won't work very well in this situation.
Solution 2 totally defeats the purpose of using Core Data in the first place unless I am missing something.
Solution 3 means the client always needs to request for all data. This is nearly impossible to do because as you get more data, the time to retrieve and process them will make the app slow and unresponsive. It also doesn't make sense from technical and UX point of view.
Solution 4 also kinda defeats the purpose of using Core Data because it's the same workflow when we only store data in memory. You can still fetch and find objects but they might be invalid on the server already at the time of access.
Am I missing something? How is Core Data supposed to be used in this scenario? How do you ensure data consistency when the client doesn't have all the data? Thanks you in advance.

Using tags for user-set UX details

I'm using acts_as_taggable_on for tagging items across my system so that they're easily searchable.
Now I have a UX problem: I'm noticing lots of places where users choose certain minor states (for example, closing a one-time help box or moving to the next javascript-run step in a given page). We have here situations that are both too minor/numerous/dynamic/fast-changing to be put into a database table (imagine having to migrate with every UX change!), and that there is a need to persist some of these choices beyond the session.
In this case, is there anything wrong with using tags to store these simple decisions? For example, user.set_tags_on(:ui, "closed_index_help") or user.set_tags_on(:ui, "tutorial_1_done"), then showing/hiding these elements in the future by looking at the user's ui_list.
Are there drawbacks to this I'm not considering or is this a prudent way to go?
Another way might be to store the information in the SESSION. You will of course have to migrate the session information to be stored in the DB rather than the cookie, but at least that way - you only have to retrieve the session once.

Storing Product List through out session

Im using MVC ASP.NET C#, jQuery
I'm building what could be decribed as the simpliest shopping cart in the world.
Basically My Clients wants users to be able to browse the site, Click on a product they want and it be added to a "list" and then when they "Checkout" they simply fill in a form and it emails my client with the list of products they had chosen!
I was thinking of something like storing them in a cookie. So as the user browses they won't be lost, Then have a jQuery dialog appear when they choose to view/checkout their cart. and it can list all products and then they simply fill in a simple form..
Is this the best way to go about it. Its a cheap website and I would like the simplest way to do this? All i guess I would need to sort is the product Id's..
Any ideas of better ways or any opinions at all!
Using Session depends on whether you think the users will pick the products in one go. Or will they leave the page and come back in an hour? The problem being that if they come back in an hour, the Session State may have been garbage collected to free up resources on the server, or the session might have expired.
To get around this, if all the products are on one page, you could store the chosen products in a hidden field, encrypted and all, that will stay there until the user closes the app.
You just need to serialize the list of product Ids, pass that serialized string to the view and put it in a hidden field.
Another option would be to store it in the users session. A benefit of this is if the user has cookies turned off and the site caters for cookieless session state then they will still be able to select products and checkout.
The thing to look out for is how much you could potentially end up storing in session. From the sounds of it this will not be an issue but if this could potentially use up an unacceptable amount of memory then you would probably need to consider a database approach anyway rather than cookies.
I'd say to go for the Session object. You can always configure the location of Sessions at runtime
I think some may dislike this storage method (it breaks testing isolation, if i'm not mistaken), but it's there for free :)
If you're using jquery, you could store the basket as a json array inside the $('body').data() element (or actually as i do, under a div called '#storage'). this works as a fantastic local storage mechanism, tho' would only be relevant to the current page that the user was on and would be cleared on moving to subsequent 'new pages' unless of course, your design was such that the shopping page was ALWAYS the same page and only refreshed by ajax methods. this way, you could continually append/modify the json structure on the 'worksurface' page.
i use this technique for a different application of the logic, but virtually for the same reason.
here's a snippet of the kind of thing i do:
/* example of data params key*/
var keyParams = "Data-Search-type-" + $('#searchtype').val();
/* add json to body with key*/
$('#storage').data(keyParams, jsonData);
/* get same data back later */
var jsonData = $('#storage').data(keyParams);
When i 'save' the data to the server, i then clear the data() element back to null. There is of course the other option of localstorage itself which can be used well, especially in disconnected environments (such as mobile apps).
another way to skin the many skinned cat!!

replace_html or insert_html

Hello stackoverflow pals.I am a new rails learner. My question is: I am listing all items in index and also i am usin some ajax in this page to insert new items to database. After inserting new items to database, should i get all items from database again and replace whole list of items or just add new item to list by using insert_html? Thank you.
Adding only the new items to the list is likely to be more responsive and will keep network traffic lower. However, it's also going to be a bit more complex for you as the programmer, since you'll have to figure out where to insert it and generally do more management of the table state. But either way can be a valid approach.
If you are keeping track of deletions client-side via AJAX and updating your client's view on delete as well as on insert you should not need to replace all the listings very often. It probably would make sense to poll the server periodically if multiple users are manipulating data at the same time so that one user doesn't end up with a stale view. You should probably look at a Comet implementation like Juggernaut in that case so that the server can push data to the client rather than relying on simple polling.
You also may want to consider beefing up your client-side Javascript and implement pure JSON passing between client and server. This way you only pass the data back and forth from your server to the client and the client's browser keeps the view up to date based on the JSON from the server and the logic you build with Javascript.
If you're at all worried about large amounts of traffic hitting the page, I would push as much as you can to the cilent. Do your insert and update the list accordingly.
If new items always go at the bottom and you can't sort them, I'd just append the new item to the bottom.
If you can sort them or need to insert it in a specific place, I'd re-render the whole table.
Personally, I wouldn't worry about the performance difference until it became a problem; I'd just go with the simplest thing that worked.

How to pass context around in a ASP.NET MVC web app

Ok, I'm a newbie to ASP.NET web apps... and web apps in general. I'm just doing a bit of a play app for an internal tool at work.
given this tutorial...
http://www.asp.net/learn/mvc-videos/video-395.aspx
The example basically has a global tasklist.
So if I wanted to do the same thing, but now I want to maintain tasks for projects. So I now select a project and I get the task list for that project. How do I keep the context of what project I have selected as I interact with the tasks? Do I encode it into the link somehow? or do you keep it in some kind of session data? or some other way?
As it sounds like you are having multiple projects with a number of tasks each, it would be best practise to let the project be set in the URL. This would require a route such as "/projects/{project}/tasks". It follows the RESTful URL principle (i.e. the URL describes the content).
Using session state will not work if a user possibly have different projects open in multiple browser windows. Let's say I am logging into your system and a selecting two projects opening in two tabs. First the session is set to the project of the first opened tab, but as soon the second tab has loaded, the session will be overwritten to this project. If I then do anything in the first tab, it will be recorded for the second project.
I use:
Session state for state that should last for multiple requests, e.g. when using wizards. I'd be careful not to put too much data here though as it can lead to scalability problems.
TempData for scenarios where you only want the state to be available for the next request (e.g. when you are redirecting to another action and you want that action to have access to the state, but you don't want it to hang around after that)
Hidden form fields [input type="hidden"] for state that pertains to the form data and that I want the the controller to know about, but I don't want that data displayed. Also can be used to push state to the client so as not to overburden server resources.
ok, From what I can tell, the best option seems to be to save it into the Session data
RESTful URLs, hidden fields, and session cookies are your friends.

Resources