Saved event is not being called the second time

Saved event is not being called the second time

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


alef posted on Sunday, November 16, 2008

Following scenario:

Put "this.Close()" in comment of the class RolesEdit.cs of the ProjectTracker application.

So the form will stay on the screen when you click Save.

Problem:

The event Roles_Saved doesn't get executed anymore when you click a second time on Save:

private void Roles_Saved(object sender, Csla.Core.SavedEventArgs e)

{

// this runs on the client and invalidates

// the RoleList cache

RoleList.InvalidateCache();

}

What can be the reason that the Roles_Saved doesn't get called anymore?

RockfordLhotka replied on Sunday, November 16, 2008

The Saved event is raised by an object instance.

When you call Save() you get back a new object instance.

Any handler for the Saved event must hook the new Saved event from the new object instance.

alef replied on Monday, November 17, 2008

This is true when you are talking about trapping the Saved event in the UI. Then you have to pay attention to subscribe to the new instance after the Save() method is been called.
But in your sample application, you trap the event also in the Business Layer. The purpose is to invalidate the cache of the RoleList collection.
So you are subscribing to the Saved event in the constructor of the Roles class

private Roles()
{
    this.Saved += new EventHandler<Csla.Core.SavedEventArgs>(Roles_Saved);
    this.AllowNew = true;
}

The weird thing is that in the UI when you click the second time on the Save button in the RolesEdit form the method private void Roles_Saved(object sender, Csla.Core.SavedEventArgs e) is not been called anymore.
Some extra information:
When you don't change anything in the
RolesEdit form then you can click as many times you want to Save button, the event is been called anytime. But when you do some changes in the RolesEdit form, then click save, the save event will also be called. But when you do again some changes, then click again on the Save button, the saved event is NOT been called anymore.

RockfordLhotka replied on Monday, November 17, 2008

Interesting. I think this is due to serialization, and it is a bug in the Roles class.

 

Now that I think about it, when the new object comes back from the server, it is deserialized onto the client. The deserialization process doesn’t run any constructors (not normal ones anyway), and so that code doesn’t execute.

 

So what’s needed is this code:

 

      protected override void OnDeserialized()

      {

        base.OnDeserialized();

        this.Saved += Roles_Saved;

      }

 

That should re-establish the event handler in the new instance.

 

I’m glad you discovered this!

 

Rocky

alef replied on Tuesday, November 18, 2008

Great. This is the missing code.
I was wondering because I'm using a 2-tier architecture (physical), so my first thought was that I don't need to worry about serializing. But after some investigation I discovered that your save method is automatically cloning the object in CSLA 3.5.2. The code for your cloning is using Serialize and Deserialize and that is the reason we have to implement OnDeserialized method. Correct me if I'm wrong.

The code I added is the following:
      protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
      {
        base.OnDeserialized(context);
        this.Saved += new EventHandler<Csla.Core.SavedEventArgs>(Roles_Saved);
      }
Alef


RockfordLhotka replied on Tuesday, November 18, 2008

You are correct, and that should be the right answer. I’ve added that code into ProjectTracker too, so the next person won’t have to figure this out :)

Rocky

 

 

From: alef [mailto:cslanet@lhotka.net]
Sent: Tuesday, November 18, 2008 7:57 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Saved event is not being called the second time

 

Great. This is the missing code.
I was wondering because I'm using a 2-tier architecture (physical), so my first thought was that I don't need to worry about serializing. But after some investigation I discovered that your save method is automatically cloning the object in CSLA 3.5.2. The code for your cloning is using Serialize and Deserialize and that is the reason we have to implement OnDeserialized method. Correct me if I'm wrong.

The code I added is the following:
      protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
      {
        base.OnDeserialized(context);
        this.Saved += new EventHandler<Csla.Core.SavedEventArgs>(Roles_Saved);
      }
Alef




Copyright (c) Marimer LLC