Persisting an object across multiple sessions in ASP.Net MVC - asp.net-mvc

What is the best way of persisting a collection of objects across multiple sessions in ASP.Net MVC? I'd like to have a collection in which many users can "take the next X" from the collection - e.g. process the next X records that someone else isn't using - so it will have to persist in the service layer across multiple sessions of the the application.
It's an internal website, so there's no worry of users getting to things they're not supposed to, it will only be used by those who should have access to the data.
Considering using a static object in the service layer, but I'm not sure how/whether that will persist across sessions, or am I approaching this entirely the wrong way and should I be using the database to store the information instead?

Yes, this definitely seems like a concern for the database - storing this in memory (ala your static variable approach) does not allow load balancing and the information will be lost each time IIS recycles the App Pool.

I would rather go the DB way. Always consuming from the same place and avoid having to keep track with multiple lists. You can get the Next X from the DB and flag them and move to the next ones

Related

Best way to store a list of objects in ASP.Net MVC

In my current project, I am building an object list from multiple database tables. I am currently storing them in the user session (Global.asax/Session_Start) as showed below.
protected void Session_Start()
{
Session.Add("listeOF", new ListOf());
}
This is working and I can use the data, but I was wondering if there's a better way to store it (by better I mean faster access). I call this data in my controllers.
You need some other data store to keep it across postback requests, so if it's global to the application, you can use application cache, but if it's specific to the user, then session is fine. If there isn't that much data involved and it's not that intensive as a read, you may want to consider whether there is a benefit to caching a chunk of data vs just re-querying it when needed.
To get more advanced and present another alternative that is more involved, a CQRS implementation is a possibility (also see this); the idea there is one data container is for transaction data, and another for reads (whether that is a separate database or table, or even a document database as some possibilities).

nHibernate w/ASP.NET Session Per Request And Active Work Item

I am building an ASP.NET application using nhibernate and I implemented the session per request architecture. Each request I am opening a session, using it, then closing it. I am using one large object across several views and I am storing the object in user session cache so it maintains state for them across several different pages. The users do not want to have to save their changes on each page, they want the ability to navigate between several pages making changes, then commit them to the DB. This works well except for when the users try to hit a page that triggers lazy loading on the proxy object (which fails due to the session per request design closing the nhibernate session in the previous request). I know that turning lazy loading off would fix it; however, that is not an option due to the performance issues it would cause in other areas. I have tried changing the session per request design but have had no luck since I do not know when it is "safe" to close the nhibernate session.
Has anyone else done anything similar to this or have any advice?
Thanks in advance!
Keeping any objects in user session - the server session, server resource is not the best approach. Just imagine, that accidently your application will be very very successful... and there will be many users... therefore many sessions == many resources.
I would suggest (based on some experience), try to re-think the architecture to avoid session. Extreme would be to go to single page application... but even some async during "...navigation among several pages..." will be better.
All that will mean, that:
we passs data to client (standard ASP.NET MVC way with rendered views or some Web Api JSON)
if needed we send data back to server (binding of forms or formatting JSON)
In these scenarios, standard NHiberante session will work. Why? Because we "reload and reassign" objects with standard NHibernat infrastructure. That would be the way I suggest to go...
But if you want to follow your way, then definitely check the merge functionality of NHibernate:
9.4.2. Updating detached objects
9.4.3. Reattaching detached objects
19.1.4. Initializing collections and proxies
Some cites:
In an application with a separate business tier, the business logic must "prepare" all collections that will be needed by the web tier before returning. This means that the business tier should load all the data and return all the data already initialized to the presentation/web tier that is required for a particular use case. Usually, the application calls NHibernateUtil.Initialize() for each collection that will be needed in the web tier (this call must occur before the session is closed) or retrieves the collection eagerly using a NHibernate query with a FETCH clause or a FetchMode.Join in ICriteria. This is usually easier if you adopt the Command pattern instead of a Session Facade.
You may also attach a previously loaded object to a new ISession with Merge() or Lock() before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!

Session State between Pages in MVC

besides TempData, which I believe isn't the best thing to use nowdays, what are some best practices in how you can persist user data from page to page?
Do you usually just go back to the DB every time...ajax or not...do you make a request every time or do you store it in lets say the Request object or some other in process object instance?
I'm just looking for a broad range of ideas as I am overwhelmed with looking this up on the net...there's a LOT out there and it would be easier for me to get some insight via stack as well.
There are several options. If we're talking about intrarequest, then of course ViewBag is the best choice. Intrapage (across requests) then the best choice is probably hidden fields, unless it's sensitive data.
Between pages, then there are several options. You can of course pass data as query string parameters. Session also makes a convenient option, so long as the data size is small, and it's ok if the session gets lost (ie, you can get it again or regenerate it). In certain other situations, you can post data to another page using hidden fields, but this should largely be discouraged since you should prefer to use PRG (Post/Redirect/Get) pattern.
Some other options are using the context cache HttpContext.Cache (Which i feel is misnamed, but oh well) or saving it in temporary tables in the database. Any "in-memory" option will have scalability issues if you decide to move to a web farm (Session can be made to be backed by database, but it slows things down).
It also depends on what data you're talking about. If it's user data, then another option is to store it in a cookie, or to use the user data portion of the Forms Authentication cookie, and create a custom IIdentity object.
Finally, there's just rebuilding the data from its source on every request.

ASP.NET MVC - what's the equivalent of ViewState

I have an existing web-forms website that runs on a web-farm (multiple web servers, each request is NON-sticky).
One of the tasks is to retrieve a lot of data from a 3rd party webservice. This is an expensive process (in terms of time taken to respond). The optimal solution has been to initially grab all the data and stick it in the page's ViewState (as a List<Product>. We then have a grid that allows us to page through this list of products. For each request for the next page we don't have to re-visit the slow web service because we've already cached the data in the ViewState.
So, how would I accomplish this using MVC? If I were using classic ASP, I would serialize the list and hold it in a hidden field in the form.
But what is the preferred approach when using MVC? As mentioned, I'm using non-sticky sessions so can't rely upon caching on the server.
If I am to hold it in a hidden-field, then is it sensible to compress the data first (zip) to reduce the size of the page? Again, what's "best practice" here?
Many thanks for any/all advice
Griff
PS - I know there are similar posts out there (e.g. ASP.NET MVC and ViewState), but they don't quite provide the detail I require.
Caching, in my humble opinion, is the best way to deal with this; hit the webservice, cache the data, and use that for each subsequent request.
It is possible to share a cache across many web servers. The default behaviour is to hold it InProcess, but this is by no means fixed and can be configured to store it in a remote InProc cache, a database, or any other method of semi-persistant storage. AzureAppFabric caching comes to mind.
Second to that, as you mentioned is to dump all the data in a hidden field, but I dont like this idea for a number of reasons
Page bloat - you're submitting this data every time the page is changed
Lost data - you must submit a form for every navigation, forgetting to do this means loosing your data
To name 2.
Your strategy should depend on how volatile the data retrieved from the 3rd party service is going to be and how expensive it is to call it.
Volatile and expensive. I would go down the road of caching the data in a distributed cache such as Appfabric Velocity, or Memcached.
Non-Volatile and expensive. Cache a copy of it in memory on each server node.
Cheap. Hit the call every time you need it. Don't bother caching.
If the data set returned from the service is large, I would not pass this up and down every time you page through your grid data. Only retrieve the data for the current page and render it in your grid. Telerik have a good implementation for this or you could try and roll your own.

ASP.NET MVC saving Entity session

I have been working with entity framework and ASP MVC for a while. I have stored the entity object in the HttpContext.Current.Session in order to use the same session at all times. Now I have encountered some problems and I am wondering if this may have been a bad idea and if so, how should I do it otherwise.
The problem I have now is that the entity object caches data and that one user cannot see changes that the other user has done.
The session is basically a hash table-like structure that is specific to a user. If you want to store data that can be seen by all users of the system, you either want to use the Application scope or caching.
This article from MS covers the different options for state management, including session and application:
http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
Caching is slightly different in that it allows you to do things like set expiration. If you don't need this kind of functionality, I would recommend sticking with application state. Article on caching from MS:
http://msdn.microsoft.com/en-us/library/6hbbsfk6(VS.71).aspx
The problem with storing Entities in memory between requests / sessions or whatever is that you have to be very careful if you have a new ObjectContext for each request / session whatever, because and entity can only be attached to one ObjectContext at a time, and can be easy to forget to detach (between requests in the same session) or to correctly share an object (between concurrent requests in different sessions).
Check out this Tip for clues on how to cache data between requests / users / sessions etc.
Hope this helps
Alex
By the book you would want your object context exist the shortest time possible.
so you create a context, grab some data, return your view to client.
and dispose everything.
Start caching when your db can't handle your load.

Resources