CSLA 4.5.10 - Xaml.ViewModelBase under Silverlight

CSLA 4.5.10 - Xaml.ViewModelBase under Silverlight

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


Jaans posted on Wednesday, January 16, 2013

Hi Rocky

Since moving over from 4.3 to 4.5 I'm experiencing a strange issue with the Xaml ViewModelBase when calling BeginSave() and the DataPortal throws an exception.

BeginSave works just fine when there is no exception on the server side data portal, however what I'm observing is that if the server side data portal throws an exception the exception is never received. Also, IsBusy stays stuck on true and OnError is never called.

I have a suspicion that the ViewModelBase class was initially a great help to work with the DataPortalResult callback pattern that was used pre-Async pattern.

I'm not sure which is now the preferred way of saving the business object under Silverlight when using the ViewModel and CSLA 4.5 with the Async pattern available.

Do we still call BeginSave() - doesn't this still employ the Callback pattern?

I see there is a new method on the ViewModel called SaveAsync() - this would typically be awaited upon, but then I'm curious what the exception handling strategy with that is, because I'm assuming that the SaveAsync on the ViewModel still sets the Error property and still calls OnError. Would an (aggregate task) exception ever be "returned" then when you call SaveAsync()?

Hopefully this makes some sense - love to get your input.

On a related note, I'm thinking that the following method is "missing" from CSLA ViewModel class:

 

        protected virtual async Task RefreshAsync( Func<Task<T>> factoryMethod )

        {

            Error = null;

            try

            {

                IsBusy = true;

                var model = await factoryMethod();

                OnRefreshing( model );

                Model = model;

                IsBusy = false;

            }

            catch ( Exception ex )

            {

                IsBusy = false;

                Error = ex;

            }

            OnRefreshed();

        }

 

 

Jaans replied on Wednesday, January 16, 2013

In addition to the above, it looks like the issue has to do with the ISupportUndo.Saved event not being raised on the Silverlight client side in the event of an exception being thrown on the server side data portal.

This event is key to the current implementations of the BeginSave() and SaveAsync() methods on the Xaml.ViewModelBase class.

If I override the SaveAsync implementation with an awaited implementation (and not use the Saved event) then the exception reaches back to the Silverlight client. So it might be that the Saved event isn't being called correctly by the DataPortalClient implementation or that the event isn't being serialised correctly.

Here's the override implementation of ViewModelBase.SaveAsync() that fixes the above bug and works quite well. Perhaps this should be the replacement implementation?

        protected override async Task<T> SaveAsync()

        {

            try

            {

                var savable = Model as Csla.Core.ISavable;

                if ( ManageObjectLifetime )

                {

                    // clone the object if possible

                    var clonable = Model as Csla.ICloneable;

                    if ( clonable != null )

                        savable = (Csla.Core.ISavable)clonable.Clone();

 

                    //apply changes

                    var undoable = savable as Csla.Core.ISupportUndo;

                    if ( undoable != null )

                        undoable.ApplyEdit();

                }

 

                Error = null;

                IsBusy = true;

                var model = await savable.SaveAsync();

                OnSaving( model as T );

                Model = (T)model;

                IsBusy = false;

                OnSaved();

                return Model;

            }

            catch ( Exception ex )

            {

                IsBusy = false;

                Error = ex;

                OnSaved();

                return null;

            }

        } 

 

As an aside: Is there a specific reason the SaveAsync implementation needs to use the saved event?

RockfordLhotka replied on Monday, January 21, 2013

Thanks for the research on this, I appreciate it, and will file a bug.

When I rewrote the data portal for 4.5 I tried to consolidate all the functionality into two workflows - sync and async. Ultimately the BeginXYZ methods will go away, because they aren't necessary with async/await. I didn't want to maintain a whole workflow for that now-legacy model, though my choice is causing some pain in the meantime :(

ngm replied on Monday, February 11, 2013

RockfordLhotka

I believe that the first issue is resolved with the changes I've made to the data portal. Hopefully you can test and confirm once I get the prerelease online.

Isn't the issue here that ViewModelBase invokes BeginSave of the BO to implement both SaveAsync and its own BeginSave and still wires up for BO's Saved event?

BO's BeginSave only invokes provided callback and never Saved event.

I don't see that Data Portal has anything to do with this.

- ngm

 

Jack replied on Saturday, February 16, 2013

I've been experiencing this issue as well but hadn't had time to dive in and figure out the issue.  I'm pretty late in my release cycle and was just wondering for a pure Silverlight release how safe should the preview version be or would I be better off modifying the existing 4.5.10 source with the suggestion above?  I only found out about the issue by accident when I broke a database package.

Thanks

jack

Jaans replied on Saturday, February 16, 2013

Hi Jack

We found that there are a few useful bits of functionality that we wanted on our view model over the years, and have for a long time now, instead used our own custom base class for our view models. This custom base class does however inherits from the CSLA ViewModel base class, and so allows us to override the functionality that doesn't work right for us (like the discussion above and also our preference for an RefreshAsync method) and add some others we feel are missing.

Bottom line, I guess, is that our needs might not always be the needs of the greater CSLA community so it makes sense to keep this custom ViewModel base class around as a default.

As for CSLA 4.5.10 stability under Silverlight, we've now released two large and CSLA intensive projects to product, with good success and stability. There are caveats though, like the issues from this discussion. There are a few others like the Silverlight factory not calling into a data portal if that data portal signature doesn't also exist on the client, despite the data portal always calling the method at the remote data portal. I think this happens mostly with DataPortal_Create scenarios, so we now need to place a "stub" for the same signature in the Silverlight code, in order to have the server side remote one get called. I think there is another discussion on the forum about that here somewhere. Not sure if this is addressed as a bug though?

Other than that, I'm pretty happy with this preview version (though the next version is due very soon if I'm not mistaken). The ability to apply the async/await behaviours are brilliant and simplifies the client side code quite a bit, even just for readability's sake.

Just be warned that if you're new to async/await pattern that there are some gotchas if you don't fully understand what it's going to do, but there are quite a few blog posts around to help if your not getting the behaviour you thought you'd get.

Hope that helps,
Jaans 

RockfordLhotka replied on Saturday, February 16, 2013

The next prerelease should be out the week of 18 Feb. The only real thing I'm still planning to do is this particular issue :)

https://github.com/MarimerLLC/csla/issues/28

Jack replied on Sunday, February 17, 2013

That sounds great… I’m glad to hear it wasn’t my code (I updated to the preview version) and I still had issues both with the old Save and calling the SaveAsync.  My app is a terrible hodgepodge of inconsistencies so jumping from 3.6x to 4.3x and 4.5x has been fun to say the least.

 

It will be nice to step back and make another pass.

As soon as you release something I will give it a whirl.  I've still got a short window left for testing.

Jack

RockfordLhotka replied on Wednesday, February 20, 2013

Version 4.5.12 is now online at www.cslanet.com and nuget, and should fix this issue. Please let me know if you have issues.

 

Jaans replied on Wednesday, February 20, 2013

Thanks Rocky!

Copyright (c) Marimer LLC