Problem with sessions in ASP.net app

Problem with sessions in ASP.net app

Old forum URL: forums.lhotka.net/forums/t/7990.aspx


Jerrycurl posted on Friday, November 13, 2009

I 'm not sure if this is a CSLA problem or not, but either way maybe someone here can help me.  I have a BusinessBase class (call it TestParentClass) which contains a collection of a child class (BusinessListBase<TestChildClasses, TestChildClass>).  All classes are marked Serializable.  My web form consists of a datagrid listing the TestChildClasses.  When the user selects a row, it opens up a panel where they can edit the properties of the selected TestChildClass.  This works fine when using the default inproc sessions.  But when I reconfigure it to store sessions in SQL Server, it doesn't work.

In my Page_Load I set the parent object like so:
  Object obj = TestParentClass.GetTestParentClass();
  Session["TestParentClass"] = obj;

When a row in the grid is selected, I retrieve the child object like so:
  TestParentClass obj = (TestParentClass)Session["TestParentClass"];
  DataGrid dg = (DataGrid)sender;
  TestChildClass testChild =  obj.TestChildClasses.GetTestChildClass(Int16.Parse(dg.SelectedItem.Cells[2].Text));
  Session["NewTestChildClass"] = testChild;
  FormView1.ChangeMode(FormViewMode.Edit);
  FormView1.DataBind();  //FormView1 uses as its datasource a CslaDataSource for TestChildClass.

When the user saves their changes to the TestChildClass:
  FormView1.UpdateItem(false);

If I step through in debug mode, I can see that Session["NewTestChildClass"] contains the updated data right after the FormView1.UpdateItem call, but the Session["TestParentClass"] still contains the old version in the collection.  Using inproc sessions, Session["TestParentClass"] contains the updated TestChildClass at the same point (which is what I want).

Here is what my datasource events look like:
protected void TestChildClassesDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
        {
            Object obj = Session["TestParentClass"];
            if (obj != null)
                e.BusinessObject = ((TestParentClass)obj).TestChildClasses;
        }

        protected void TestChildClassDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
        {
            Object obj = Session["NewTestChildClass"];
            if (obj != null)
                e.BusinessObject = obj;
        }

        protected void TestChildClassDataSource_UpdateObject(object sender, Csla.Web.UpdateObjectArgs e)
        {
            Csla.Data.DataMapper.Map(e.Values, Session["NewTestChildClass"]);
        }

Does anyone see any glaring problems with this code?  It just seems strange to me that it would work with inproc sessions, but not sql sessions (I thought they were supposed to be pretty much interchangable).  Thanks for any help.  Oh, I'm using Csla version 3.0.5-081009, if that matters.

-Jerrad

JoeFallon1 replied on Friday, November 13, 2009

The key thing to look for is the Serializable attribute on all your BOs in the hierarchy. Root, Collection, Child, etc.

InProc works because the data never gets serialized anywhere.

State Server and SQL Server require you to actually serialize the Session to a blob and send it someplace.

Joe

 

Jerrycurl replied on Monday, November 16, 2009

Well, I'm only using the three classes I mentioned, and they are all marked  [Serializable()].  Is there something else I need to do?

When I assign the session variable,
  Object obj = TestParentClass.GetTestParentClass();
  Session["TestParentClass"] = obj;

it successfully contains the complete hierarchy.  And I can successfully edit the children like so:
  ((TestParentClass)[Session["TestParentClass"]).TestChildrenClasses[5].ChildProperty = "whatever";
Doesn't that mean that the serialization is working?

It's as if the Session["NewTestChildClass"] variable is copied by reference when using inproc sessions, but copied by value when using sql sessions.  I think I can make things work by manually copying the updated child properties back into the parent's copy of the child, but I'd rather not go that route if I don't have to.

JoeFallon1 replied on Monday, November 16, 2009

I am not sure why you have separate session variables for your root and child objects. That is a problem right there. If the root is supposed to contain the child then just set the root.child property and store the root in session by itself. Then when you call the root out of session the root.child property should have the values you want.

Joe

 

Jerrycurl replied on Monday, November 16, 2009

Thanks, that works.  When adding a new child to the parent, I create a new child object and store it in a session variable which eventually gets added to the child collection in the parent (if the user doesn't cancel).  I guess I was just carrying over the same logic to the update functions.

Copyright (c) Marimer LLC