views:

66

answers:

4

Be careful when storing a model in a session. It will behave differently than you expect and can easily get out of sync with the database. Instead of storing the model directly in the session, store the id to the model and use that to fetch it from the database.

Is it best practice like above to just put the id of the model into the session and then extract it later, or should I pass the whole model?

+1  A: 

It depends on the model. If it is an entity that is only relevant to the current user, then by implication it probably won't change via another user or system and the session is as good a place as anywhere else to store it.* It also might make sense to store a copy per-user if it is something that each user frequently affects.

On the other hand, if the entity is shared between users, you should store it in cache or another centralized persistence medium so that there is only ever one authoritative copy; and to avoid wasting memory on duplicate entries.

*However, this opens an entirely different set of questions around caching versus going to the database every time, which can only be answered by a thorough architectural review of the application and usage patterns. Is WFE (web front-end) memory in less demand than database connections. Is the hit of retrieving an entity over and over more or less than keeping copies in other places?

Rex M
It's for a form to order a product.
ebb
@ebb then you probably just answered the question!
Rex M
Store the ID in session instead of the model :)?
ebb
A: 

I wouldn't store entire models in the Session and would lean towards the ID method. The reason being that the Session will persist for the entire time the user is on your site and it wouldn't be cleaned up after the user has moved to a diff page that no longer requires the data. What if the user access many pages that you do this type of storage on? It could lead to a lot of wasted memory.

If this is data that could be used by many users you might want to consider using Cache instead of Session as it will save you duplicating the same data across multiple sessions.

EDIT: Noticed your note saying it was an order form. You could use the Session to store the 'current order' for the user and clear it / replace it as they submit / create orders. Would you need to store it because there are multiple steps? In some cases if it is very limitted data, you could store it in cookies and then makes sure to clear the cookie once the order is done.

Kelsey
The reason for storing data/id in the session is that its dynamic generated html elements (textboxes etc.) and therefor when doing the validation it loops through all of the html elements in the specific product category and checks for errors (length, regex, allownull etc.) - So the session actually contains the ID for those elements. - So yes when they submit and its successfull then it should clear the session.
ebb
A: 

Yes, it is a best practice to store just the ID and then retreive/update the record from the database when you need it.

If you store the entire object in session, you are basically caching it, and you need to be aware of all the relevant caching issues (stale data, memory size, etc).

The advantage of keeping the whole thing

  • Not having to go back to the database (quicker if the session is in memory)

The disadvantages would be

  • If another user/process updates that record, you now have an out of sync record.
  • Possible memory issues since you could be storing a lot of data in session and aren't managing it as a whole.

You'll basically be removing a level of complexity in your application (though adding an extra call to the db) by just storing the id.

Alan Jackson
What about if I need to store the user input into a session so I can redirect to a confirm page? - Then I "have" to put the model into the session..
ebb
In that case, the user input probably isn't in the database yet so it's not really an issue. I'd suggest using a post variable to send the user input to the new page rather than using the session as well.
Alan Jackson
A: 

What about if I need to store the user input into a session so I can redirect to a confirm page? - Then I "have" to put the model into the session

In that scenario you don't need to put it in the session at all. Have the post made to the confirmation page directly, there you grab the values from the post. In the confirmation page, send the values back to the client / hidden field or fields, depending on how you decide to send it.

There are also various alternatives that don't involve using the session.

eglasius
Well.. lets say you have page where you enter the data, and then when you click submit and the validation is successfull it redirects you to a confirmation page. The confirmation page should just be a bunch of labels/paragraphs describing what the user have entered in the fields at the previous page and a "Back" button if they want to change anything... So the data from the previous page should that be stored in a hidden serialized field or something to be able to send it when they click "Order" at the confirmation page?
ebb
@ebb yes, serializing is a way to store it in a hidden field. You need to run it through the same validation method you used in the original post, won't trigger anything for regular users but you can't trust user input. A similar option is to store it in the ViewState of the page, which causes it to be serialized and have some level of tamper protection (safer to validate it anyway).
eglasius
Using ASP.NET MVC so.. no ViewState :)
ebb
@ebb asp.net mvc 2 has a method you can call for it to serialize / sign the field, end result is a hidden field you explicitely define but looks a lot like the viewstate. In MVC I tend to explicitly send the separate hidden fields myself / as I said I run the same original validation anyway.
eglasius
Both and.. I have been around the serialize/deserialize thing that comes with the MVC future assembly.. but It have one major problem.. if you copy another base 64char array into the field instead of the serialized value then its accepted, and passed.
ebb
that's where "run the same original validation" saves the day. Also I prefer to explicitly handle double submit, than having the user loose their input because the app domain was recycled and the asp.net Session was lost.
eglasius