Repository: MarimerLLC/csla

Issue #1125: "Edit level mismatch in AcceptChanges" Error When Saving BusinessListBase Directly
Created: 2019-04-08T22:02:04Z
Describe the bug
The changes to serialization and deserialization of edit levels in #1083 have caused a new issue when saving a BusinessListBase that is not a child list of another object.
Version and Platform
CSLA version: 4.10.0
OS: Windows 10
Platform: WPF
Code that Fails
In BusinessListBase.cs:
private void AcceptChanges(int parentEditLevel)
    {
      if (this.EditLevel - 1 != parentEditLevel)
        throw new UndoException(string.Format(Resources.EditLevelMismatchException, "AcceptChanges"), this.GetType().Name, _parent != null ? _parent.GetType().Name : null, this.EditLevel, parentEditLevel + 1);

      // we are coming up one edit level
      _editLevel -= 1;
      if (_editLevel < 0) _editLevel = 0;

      // cascade the call to all child objects
      foreach (C child in this)
      {
        child.AcceptChanges(_editLevel, false);
        // if item is below its point of addition, lower point of addition
        if (child.EditLevelAdded > _editLevel) child.EditLevelAdded = _editLevel;
      }

      // cascade the call to all deleted child objects
      for (int index = DeletedList.Count - 1; index >= 0; index--)
      {
        C child = DeletedList[index];
        child.AcceptChanges(_editLevel, false);
        // if item is below its point of addition, remove
        if (child.EditLevelAdded > _editLevel)
          DeletedList.RemoveAt(index);
      }
    }
This method sets _editLevel to 0 any time the current value is < 0. It then calls AcceptChanges on each child object in the list. Before the changes in #1083, _editLevel  would have typically been greater than or equal to 1 when this method is called on a cloned object when saving from ViewModelBase. However, with this change, it will always be 0, which then causes the argument validation on the AcceptChanges method for child objects to fail.

Duplicate issue #1212: CSLA 4.11.1 breaks deletions when root object is list
Created: 2019-07-22T19:16:15Z
Question
The change to UndoableBase in #1191 seems to have caused a new problem in my scenario. In order to delete an item from my list, i'm calling DoRemove(myItem) followed by SaveAsync. Since ViewModelBase.SaveAsync clones the list, and your change below removes _stateStack from being serialized in UndoableBase.OnGetState and UndoableBase.OnSetState, when BusinessListBase.AcceptChanges is called, the loop through DeletedList that calls C.AcceptChanges throws an exception because C.EditLevel - 1 ends up being -1 while parentEditLevel is 0.
In a similar style to my previous issue, see if this breaks for you as well
DiariesVM lvm = DiariesVM.Fetch(); //Assume this creates a DiariesVM that has a BusinessListBase Model containing 2 Diary BusinessBase objects
lvm.DoRemove(lvm.Model[0]);
lvm.SaveAsync();

Code removed from CSLA UndoableBase

UndoableBase Failure Point

Version and Platform
CSLA version: 4.11.1
OS: Windows
Platform: Xamarin

Closing comment (2019-07-30T23:12:23Z): This is possibly related to #1125 which I discovered after implementing the fix for #1080. I’ll be able to take a closer look at it in the morning.