Async DataPortal Criteria problem

Async DataPortal Criteria problem

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


theGov posted on Thursday, May 27, 2010

I have a problem where the Async DataPortal is not passing data (via arguments) to a DAL Fetch() method (via the ObjectFactory pattern). The same DAL and arguments work fine when invoked synchronously.

BusinessObject:

 

 

[Csla.Server.

 

ObjectFactory("Csla_ProjectTracker_BusObj.DAL.ProjectDAL_EditRoot, Csla_ProjectTracker_BusObj")]

[Serializable]

 

 

 

public partial class Project_EditRoot : BusinessBase< Project_EditRoot >

{

....  properties (business methods)

 

     [

 

Serializable]

 

 

 

     public partial class ParmValues : CriteriaBase<ParmValues>

     {      // embedded class in business object used to pass various criteria

         string Name = null;

         string ???? = null;   // fields for all criteria choices

         ParmValues(string name) { this.Name = name; }

     }   

     #region Factory methods

 

 

 

 

 

 

    public static Project_EditRoot GetProject_EditRoot(string name)

    {      // this works.  value set in parms.Name  is seen in DAL Fetch(parms)

 

 

 

        ParmValues parms = new ParmValues(name);

 

 

 

        return DataPortal.Fetch< Project_EditRoot >(parms);

    }

 

 

      public static void GetProject_EditRoot(string name,    EventHandler<DataPortalResult< Project_EditRoot >> callback)

     {   // this does NOT work   parms.Name in DAL Fetch(parms) is null.

 

 

        var dp = new DataPortal< Project_EditRoot >();

        dp.FetchCompleted += callback;

 

 

        ParmValues parms = new ParmValues(name);

        dp.BeginFetch(parms);

     }

 

 

   #endregion

}

If I create a DAL Fetch(string name) signature, then the value passes OK as a simple type. It seems the Async data portal processing does not persist values contained in complex types. OR am I doing something incorrect?

 

JonnyBee replied on Friday, May 28, 2010

Hi

Which version of CSLA are you using and how is the Fetch method defined in your ObjectFactory?

theGov replied on Friday, May 28, 2010

It's CSLA 4 Beta 2.

The fetch() in the DAL is:

 

 

internal BusObj.Project_EditRootList Fetch(BusObj.Project_EditRootList.ParmValues parms)

{

   ....

}

edore replied on Monday, May 31, 2010

I don't see all of your ParamValues implementation but I suggest you override OnGetState and OnSetState to handle the serialization and deserialization of your criteria class.  That's what we do when we use criteria classes in an async (or not) factory method called from a SL client.

theGov replied on Tuesday, June 01, 2010

Thanks for the reply. Is it possible you could include example code?

edore replied on Wednesday, June 02, 2010

Let's suppose you have 2 private fields in your criteria class, named _intField and _stringField.

protected override void OnGetState(SerializationInfo info, StateMode mode)

{

 

base.OnGetState(info, mode);  

info.AddValue("_stringField", _stringField);

info.AddValue("_intField", _intField);

 

 

}

 

protected override void OnSetState(SerializationInfo info, StateMode mode)

{

base.OnSetState(info, mode);

Hope this helps!

_stringField = info.GetValue<string>("_stringField");

_intField = info.GetValue<int>("_intField");

 

 

}

If your criteria class also has some reference type fields, you should also handle serialization by overriding OnGetChildren and OnSetChildren.  For example, let's suppose you have a field named SelectedEmployee of type Employee.

protected override void OnGetChildren(SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter)

 

{

 

 

 

base.OnGetChildren(info, formatter);

 

var employeeFieldManagerInfo = formatter.SerializeObject(SelectedEmployee );

 

info.AddChild("SelectedEmployee ", employeeFieldManagerInfo.ReferenceId);

}

protected override void OnSetChildren(SerializationInfo info, Csla.Serialization.Mobile.MobileFormatter formatter)

{

base.OnSetChildren(info, formatter);

var employeeData = info.Children["SelectedEmployee "];

SelectedEmployee = (

 

Employee)formatter.GetObject(employeeData.ReferenceId);

 

}

 

theGov replied on Wednesday, June 02, 2010

Thanks for the samples. I'll look into my various options.

But, just to clarify my post. None of my fields are private, they are all public.

The structure serilizes just fine when using synchronous DataPortal calls.  The only case serilization fails is when using the exact same code with asynchronous DataPortal calls.  This seemed like it was a bug in CSLA.

RockfordLhotka replied on Wednesday, June 02, 2010

I've put it on the bug list, and will try to replicate the issue when I get a chance.

RockfordLhotka replied on Wednesday, June 02, 2010

Also, you said you are using CSLA 4 beta 2 - but are you using Silverlight, or WPF?

theGov replied on Wednesday, June 02, 2010

I'm using SilverLight

theGov replied on Wednesday, June 02, 2010

Also, my current structures are using fields. I also tried converting a couple of the fields (not all) to properties, and it still was failing.

RockfordLhotka replied on Wednesday, June 02, 2010

OK, and you are aware that if you are using fields it is your responsibility to participate in the serialization process right? So you have overrides of OnGetState and OnSetState and are properly getting and putting your field data into the serialization context?

theGov replied on Thursday, June 03, 2010

I was not aware of that.  Since this was working OK in an old web project, and the only change for SL was using async methods I assumed that something was not working correctly. I was not aware that SL had this requirement.

Does this mean that I should follow the sample code above for the SL business objects only, in my style I'm using conditional compliation statements in the business objects. Or is this a general practice, and I was just lucky it worked before with the old web project?

RockfordLhotka replied on Thursday, June 03, 2010

CSLA .NET for Silverlight includes its own serializer - MobileFormatter. If you search the forum for MobileFormatter you'll almost certainly find numerous good threads. There are also several blog posts on my blog about this, most notably these:

http://www.lhotka.net/weblog/CSLALightObjectSerialization.aspx

http://www.lhotka.net/weblog/CSLALightSerializationImplementation.aspx

http://www.lhotka.net/weblog/CSLALightDataPortalAndNlevelUndo.aspx

http://www.lhotka.net/weblog/CSLALightDataPortalOptions.aspx

MobileFormatter exists to overcome the fact that SL doesn't have a BinaryFormatter or NDCS. It doesn't have them, because of SL limitations on reflection that make it impossible to create such serializers.

MobileFormatter overcomes this by requiring the participation of the objects it is serializing. The new managed backing field syntax (well, "new" is relative since I added this syntax in 3.5 in anticipation of Silverlight coming along, so it is now several years old) allows CSLA to automatically handle the details for you. But if you are using private backing fields then you must write the code to include those fields in the serialization process.

subhaskar replied on Thursday, June 03, 2010

RockfordLhotka

CSLA .NET for Silverlight includes its own serializer - MobileFormatter. If you search the forum for MobileFormatter you'll almost certainly find numerous good threads. There are also several blog posts on my blog about this, most notably these:

http://www.lhotka.net/weblog/CSLALightObjectSerialization.aspx

http://www.lhotka.net/weblog/CSLALightSerializationImplementation.aspx

http://www.lhotka.net/weblog/CSLALightDataPortalAndNlevelUndo.aspx

http://www.lhotka.net/weblog/CSLALightDataPortalOptions.aspx

MobileFormatter exists to overcome the fact that SL doesn't have a BinaryFormatter or NDCS. It doesn't have them, because of SL limitations on reflection that make it impossible to create such serializers.

MobileFormatter overcomes this by requiring the participation of the objects it is serializing. The new managed backing field syntax (well, "new" is relative since I added this syntax in 3.5 in anticipation of Silverlight coming along, so it is now several years old) allows CSLA to automatically handle the details for you. But if you are using private backing fields then you must write the code to include those fields in the serialization process.

Thanks for posting those links. They helped me too. Thanks again :)

Shubhas Sarkarronald Cruzag

Copyright (c) Marimer LLC