How to restore object after exception during saving?

How to restore object after exception during saving?

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


maxal posted on Wednesday, August 25, 2010

I need advise about restoring original object after Saving failed. Here is what I am doing:

I use ViewModelBase for my WPF application with ManageObjectLifetime set to false, since I want to control it myself.

1. "Edit" button pressed,  I call ISupportUndo.BeginEdit. Object considered to be in edit mode. EditLevel = 1

2. Save button called

ISupportUndo.ApplyEdit called. Suppose all rules are fine, EditLevel = 0

I call BeginSave from the base class, When saving into the database Unique Index exception is thrown

3. I handle OnError and OnSaved, proper error message is shown, Model is not changed. But I am no longer in "Edit" mode. My EditLevel is 0, I cannot Press Cancel and restore to original values as I could before pressing Save.

What I want to have is the same state as before pressing Save button.

I can try to save object clone before pressing Save, but it looks like hack. What would be more elegant solution?

 

I tried to search for the answer but all I could find is this: http://forums.lhotka.net/forums/p/6103/29610.aspx. And there is no solution there.

 

RockfordLhotka replied on Wednesday, August 25, 2010

If you want the Cancel button to work so the user can cancel after an exception during save, you will need to take a clone of the object graph before calling ApplyEdit.

ApplyEdit tells the graph that you are done - it commits all changes in memory. There is no cancel after that point.

So if you want to cancel, you need to have a copy of the graph from before the ApplyEdit.

maxal replied on Wednesday, August 25, 2010

Thank you for such quick reply. Will do that. I don't want user to see the difference between errors from validation rules, exception on the client or exceptions on the server.

maxal replied on Tuesday, March 29, 2011

I did what was advised and now I seems to have a problem with this with some very specific sequence of events. I am using ViewModel from Csla.Xaml

-- Edit button pressed

1. Begin Edit is called

2. Data modified the way some rules are broken

--- User presses Save button

3. Clone is created using IClonable.GetClone method

4. ApplyEdit is called

5. Begin Save is called which results in Error

6. Model is set to previously saved Clone

-- User presses Cancel button

7. CancelEdit is called

-- Edit button pressed

8. Begin Edit is called again

9. Object is modified to have rules broken again

-- User presses Save button

10. Clone is created

And here we have interesting thing. In this new clone, BusinessRules.Target is incorrect. It looks that's another duplicate instance of an object is created and BusinessRules.Target points to it.

 

I would appreciate if you point into any direction. I am going to create stripped down example with dummy object to duplicate it.

maxal replied on Wednesday, March 30, 2011

I found my problem. Please disregard my question.

ajj3085 replied on Wednesday, March 30, 2011

Would you mind sharing what the problem and solution was?  Maybe it could help others.

maxal replied on Thursday, March 31, 2011

Sure,

I didn't get to the very bottom of it, but generally, we had some non-CSLA class as part of our business object. In this class we were not careful about serialization. The biggest issue was that this class referenced our business object and our object referenced this class, and these references were not marked as [NonSerializable].

At this moment I just commented few things out, we are going to address it little bit later. But I believe having these references created "shadow" copy of our business object during "CancelEdit" operation. And then, we the clone was created, business rules switched to this shadow copy. As I said it required very specific steps to reproduce to get to this problem.

1. BeginEdit

2.GetClone

3.Clone.CancelEdit

4.CloneBeginEdit

5.GetClone from first Clone

And only on this second clone we have the problem. Not earlier, not until CancelEdit involved.

Copyright (c) Marimer LLC