-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: Keeping objects in Session variable or not?
PostPosted: Thu Jul 21, 2005 4:07 pm 
Beginner
Beginner

Joined: Tue May 17, 2005 2:48 pm
Posts: 47
In a WebForm where the user can add orders to a customer resides the following code (assuming we have no orders yet for this customer):
Code:
private void btnAdd_Click(object sender, System.EventArgs e)
{
  Order order = new Order();
  _customer.Orders.Add(order);



After this code, the count of _customer.Orders is 1.
At this time, the new order is not yet saved in the database.
To save the new order in the database, we can click the Save-button:
Code:
private void btnSave_Click(object sender, System.EventArgs e)
{
  SaveOrder;
}


When the user clicks the Save-button
- The Page_Load of the WebForm is triggered
- btnSave_Click is triggered

Because the buttonclick triggers a new request to the webserver, the current state of the customer (with 1 order) is lost. Somehow, I need to save the instance of the customer somewhere (as a Session-variable maybe?). Before SaveOrder is called this instance needs to be back, so the order can also be saved.

What is a good practice in this kind of situation?

Regards,
JackBigMac


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 21, 2005 7:22 pm 
Beginner
Beginner

Joined: Wed Jun 01, 2005 3:22 pm
Posts: 38
Location: Menlo Park, CA
The first question you have to ask yourself is, "Do I want the user to lose their order completely if they don't explicitly Save it before they close their browser or their Session times out?"

If the answer is NO, then your solution is simple: save the order to the database immediately with an Incomplete flag set.

If you do not care if they customers lose their order if they dont' Save them, then you have a few choices.

1. You can store the Order object in the ViewState.

Code:
protected Order _order
{
   get
   {
       return (Order)ViewState["_order"];
   }
   set
   {
      ViewState["_order"] = value;
   }
}


ViewState is stored in a hidden input field. That means it will exist for as long as the user keeps their browser window open on that page and no longer. However, if the user opens a new browser window, they won't be able to see orders that are in the ViewState of another window.

2. You can store the Order object(s) in the Session. Sessions time out after a set period of time. Furthermore, the user will get disconnected from the Session if they close their browser (since the SessionID cookie is a temporary one), but the Session will not time out immediately. Session also get destroyed if the Application restarts, which can happen at any time (any time your app reaches a certain memory limit, it will get automatically recycled). For this last reason, I follow the rule "Don't write to the Session anywhere other than Session_Start." In general, be very, very careful with use of the Session. Be aware of how much data you are putting in the Session and never put anything with unmanaged resources (like DB connections or file handles) in the Session.

3. You can store the object in the HttpContext.Cache. This gives you much, much more control over how long the object stays in server memory. IIRC, Session is just a wrapper around Cache anyhow. Unlike Session, Cache is independant of the user's SessionID cookie. Cache will still dissappear if the application restarts, however. Using the Cache will require a good bit of RTFM-fu, but it's worth it for lots of other things as well. The built-in Cache functionality in ASP.NET is very cool.


You might look into the "Second Level Cache" functionality in NHibernate.Contrib as well. I haven't quite RTFM'd that deep yet since I haven't needed it on any of my NHibernate-using projects yet.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 26, 2005 2:23 pm 
Beginner
Beginner

Joined: Tue May 17, 2005 2:48 pm
Posts: 47
As you suggested, I tried to add the object to the viewstate, but I got an error:

Exception Details: System.Web.HttpException: The type 'TestApp.Core.Domain.Order' must be marked as Serializable or have a TypeConverter other than ReferenceConverter to be put in viewstate.

So, I marked the class as Serializable but I keep getting the same error. Marking the class as Serializable:
Code:
[Serializable]
public class Order
{
//All the other stuff
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 27, 2005 12:07 pm 
Beginner
Beginner

Joined: Thu May 12, 2005 2:14 am
Posts: 33
Location: Sweden, Sk
Hi

Does the orderobject have any relationships. eg order.customer, order.OrderRows and so on. Dont forget to mark thoose classes as as serializable too.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 29, 2005 2:58 pm 
Beginner
Beginner

Joined: Wed Jun 01, 2005 3:22 pm
Posts: 38
Location: Menlo Park, CA
Right. To put something in ViewState, everything that object and all its children (in or out of collections) refer to must be Serializable.

Unfortunately, the exception won't tell you which object you tried to serialize wasn't serializable.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 10:43 am 
Newbie

Joined: Thu Jun 02, 2005 6:00 am
Posts: 12
Location: Ostrava, Czech Republic
You guys are doing a BIG mistake by overusing viewstate. I would personally avoid it completly. It slows everything down, as it is pushed to client and back to server all the time (viewtate as big as 200-300kb is not exception when using big form).
Besides it is not safe, everyone can read what is in it (in basic configuration it is only base64 encoded or so) - http://www.pluralsight.com/tools.aspx

For storing larger objects use Session. You can configure the session to be out-of-process so that it does not vanish upon restrting the application. It needs running windows service however.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 02, 2005 4:21 pm 
Beginner
Beginner

Joined: Tue May 17, 2005 2:48 pm
Posts: 47
Ok, now I use a Session variable to store the instance of an order:
Code:
protected Order _order
{
  get {return (Order)Session["_order"]; }
  set { Session["_order"] = value; }
}


But now, when I change a property of the Order object, I get an exception when I want to save the object: {"another object with the same id was already associated with the session: [Order#1]" }
I think this is strange, since I only have one object, am I wrong?
When I write the order to the Session variable, there's no other instance of Order involved.

Is anyone familiar with this exception?

Greets,
JackBigMac


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 15, 2005 6:25 pm 
Beginner
Beginner

Joined: Wed Jun 01, 2005 3:22 pm
Posts: 38
Location: Menlo Park, CA
DALT wrote:
You guys are doing a BIG mistake by overusing viewstate. I would personally avoid it completly. It slows everything down, as it is pushed to client and back to server all the time (viewtate as big as 200-300kb is not exception when using big form).
Besides it is not safe, everyone can read what is in it (in basic configuration it is only base64 encoded or so) - http://www.pluralsight.com/tools.aspx

For storing larger objects use Session. You can configure the session to be out-of-process so that it does not vanish upon restrting the application. It needs running windows service however.


If you store BIG objects in the Session, you're going to run into memory usage problems that really hurt scalability. Furthermore, Sessions get disconnected. Even if you move the Session out of process, the user can close their browser or otherwise delete their cookies, leaving stale Sessions sitting around taking up memory.

IMO, never write anything to Session from anywhere other than Session_Start. For every other time you're tempted to use Session, use Cache instead (IIRC, Session is just a wrapper around Cache anyhow).

Yes, ViewState is sent with every request and response.

Yes, that means you should be careful of what you put in ViewState and only put what is necessary in ViewState. But putting 6K of object data in ViewState is nothing, especially compared to even a small image on the page.

Yes, you cannot trust the contents of ViewState to not be altered (though there are ways to mitigate it with MachineKey in the Config).

Yes, people can read what's in ViewState.

But ViewState is still often the best place to put things.

ViewState vs. Session vs. Cache vs. Application vs. Static variables is not a question that can be simplified to "don't ever use X, use Y". They all exist for a reason and they all have their appropriate uses.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 6:32 am 
Newbie

Joined: Thu Jun 02, 2005 6:00 am
Posts: 12
Location: Ostrava, Czech Republic
You probably misunderstood my comment. I DID NOT try to flame viewstate. I just wanted to point out, that things shoud be used where appropriate - and I find using ViewsState for storing nhibernate persistent object as inapropriate. That is OVERUSING.
Every fundamentalism leads to hell.
Use viewstate as you like, it might be useful for storing state of the form, but I cannot find much more use.

As for the session: I personally use session to store just small objects. Larger does not mean BIG.
Cache is of much bigger use, I use it for example to store a navigation Tree object.
And I don't need ViewState at all, because I am using Maverick framework.
Othervise I completly agree with you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.