Determining if an object has at least one save attempt

Determining if an object has at least one save attempt

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


Fireworks posted on Tuesday, August 29, 2006

Hi,

It's a bit more complicated than the title.  I have a web page (Master/Detail) that has a 'Next' button (linkbutton).  Think wizard.

If the user navigates to the page and doesn't fill out a detail record and save, they should be able to navigate away from the page when they click on 'Next'.  If they partially fill in an object, and click 'Next', I want to try to save the object, and halt navigation if there are any brokenrules; to get them to correct or cancel out.
 
Is there a way to determine if an object is new but has never had an attempted save?  This would be my 'continue' condition. 

I want to be able to check the object to see if it is new but no attempted saves, in which case I will allow navigation.  If there has been an attempt to save it, I will try to save again, and show broken rules, if there is any.

It occured to me that maybe there was something in the edit levels (cloning?) that I could use.  Like comparing the snapshots of the objects.  I'm just guessing here as I don't really know how the edit levels work. 

Any help would be greatly appreciated.  Changing the CSLA framework code is open as an option.

RockfordLhotka replied on Tuesday, August 29, 2006

This is the purpose behind IsDirty. If an object IsDirty, then it has been changed and not saved (because saving marks IsDirty as false).

Fireworks replied on Tuesday, August 29, 2006

RockfordLhotka:
This is the purpose behind IsDirty. If an object IsDirty, then it has been changed and not saved (because saving marks IsDirty as false).


True.  But at least for me (the architecture guys have made some changes to the framework code), a 'new' object has IsDirty = true immediately, with just default values, and only changes to false after a successful save.

I need to tell the difference between an object that is new, but has default values, and one that is new but has had data changed.

Thanks for getting involved Rocky.



xal replied on Tuesday, August 29, 2006

You could create your own IsDirty flag and change it by overriding OnPropertyChanged()...

Andrés

Q Johnson replied on Tuesday, August 29, 2006

Should this really be the business object's responsibility?  If so, we don't have to persist all the properties of our business objects. 

With that in mind, it seems most direct to simply have an integer property called something like SaveAttempts (initialized with a value of zero, of course) to keep track of the number of times the object's .Save method is called.  You could increment it in your BO's Save method code before calling MyBase.Save, for example.  Or you could make it the explicit responsibility of the UI (incrementing the value immediately before calling the Save method), if you feel that is a better division of responsibility. 

Since a successful Save operation will return a New object, the count would be zero after a succesful Save, which it seems is exactly the behavior you want, right?

Keep in mind that the object won't be New any more once you have completed a successful Save.  So your "continue condition" should probably not be concerned with the .IsNew property at all.  It should just test .IsValid (which should be false if the Broken Rules collection isn't empty) and SaveAttempts = 0. 

 

Fireworks replied on Tuesday, August 29, 2006

Q Johnson:

With that in mind, it seems most direct to simply have an integer property called something like SaveAttempts (initialized with a value of zero, of course) to keep track of the number of times the object's .Save method is called.  You could increment it in your BO's Save method code before calling MyBase.Save, for example.  Or you could make it the explicit responsibility of the UI (incrementing the value immediately before calling the Save method), if you feel that is a better division of responsibility. 



I had thought of that.  I might just do that to get things off the ground, and let the architecture guys get wind of it later :)

I could just add a public method that calls MarkClean(), or do the same for IsDirty (suggested above).

I just wanted to make sure that I hadn't missed something.

Big thank you to everybody!

RockfordLhotka replied on Tuesday, August 29, 2006

The behavior of IsDirty is true if IsNew is true is default CSLA behavior, and follows the rules I defined in the book for these properties. IsDirty means that one or more fields in the object are believed to not match values in the database - which is obviously the case for any new object. IsNew means that the primary identifying values/keys of the object don't have corresponding values in the database, which is also the case for any new object.

However, the desire to have a new object NOT be dirty is not unique to you. It has come up many times on the forum (the old one anyway), and as a result in 2.0 I changed MarkNew() to be Overridable/virtual specifically so you could change the behavior.

So what you may prefer to do is override MarkNew like this

    protected override void MarkNew()
    {
      base.MarkNew();
      MarkClean();
    }

This way your object is new, but not dirty.

Note that MarkNew() is not called when an object is created, so you'll also have to explicitly call it in your constructor.

Copyright (c) Marimer LLC