SL 3.8.1 dp.BeginExecute(cmd) call not getting through to DataPortal_Execute() method

SL 3.8.1 dp.BeginExecute(cmd) call not getting through to DataPortal_Execute() method

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


Russ posted on Tuesday, February 02, 2010

I'm having difficulty getting a CSLA Light Command object to function. I have created a command class called UpdateLastLogonCO which the client calls to update the database last login info after the user has successfully logged in.

Stepping through the code I can verify that the "dp.BeginExecute(new UpdateLastLogonCO(userapplicationpk, lastlogin, lastlogininfo));" line is run. A breakpoint added to the Server DataPortal_Execute() is never hit.

I think I have checked everything 20 times. I cannot see why the call fails to cross the data portal.

Questions:

1) Have I implemented this correctly?
2) What options are available for debugging this type of code?


Here is the client calling code:

// update database with last logon time and info
string lastlogoninfo = string.Format("{0} [{1}] - {2} {3}", MachineName, UID, AppName, AppVersion);
Business.Security.UpdateLastLogonCO.Execute(userapppk, DateTime.Now, "", (o2, arg2) =>
{
if (arg2.Object != null)
{
var obj = arg2.Object as Business.Security.UpdateLastLogonCO;
if (obj != null)
{
if (!obj.Result)
{
// update failed
MessageBox.Show("Error updating Last Login information.");
}
}
}
});



Here are the 3 separate partial files that make up the UpdateLastLogonCO class.

UpdateLastLogonCO.Client.cs (Client)
UpdateLastLogonCO.cs (Mobile)
UpdateLastLogonCO.Server.cs (Server)


The mobile portion:

using System;
using Csla;
using Csla.Serialization;
using Csla.Serialization.Mobile;

namespace Business.Security
{
[Serializable]
public partial class UpdateLastLogonCO : CommandBase
{
public int UserApplicationPK { get; private set; }
public DateTime LastLogin { get; private set; }
public string LastLoginInfo { get; private set; }
public bool Result { get; private set; }

private UpdateLastLogonCO(int userapplicationpk, DateTime lastlogin, string lastlogininfo)
{
/* require use of factory methods */
UserApplicationPK = userapplicationpk;
LastLogin = lastlogin;
LastLoginInfo = lastlogininfo;
}
}
}


The Client portion:

using System;
using Csla;

namespace Business.Security
{
public partial class UpdateLastLogonCO
{
#region Client Factory Methods

public static void Execute(int userapplicationpk, DateTime lastlogin, string lastlogininfo,
EventHandler> callback)
{
var dp = new DataPortal();
dp.FetchCompleted += callback;
dp.BeginExecute(new UpdateLastLogonCO(userapplicationpk, lastlogin, lastlogininfo));
}

#endregion
}
}


The Server portion:

using System;
using Csla;
using Csla.Data;
using System.Linq;

namespace Business.Security
{
public partial class UpdateLastLogonCO
{
#region Factory Methods

public static bool Execute(int userapplicationpk, DateTime lastlogin, string lastlogininfo)
{
if (!CanExecuteCommand())
throw new System.Security.SecurityException("Not authorized to execute command");

UpdateLastLogonCO cmd = new UpdateLastLogonCO(userapplicationpk, lastlogin, lastlogininfo);
cmd = DataPortal.Execute(cmd);
return cmd.Result;
}

#endregion

#region Server-side Code

protected override void DataPortal_Execute()
{
// set Result true if sp returns no errors
using (var ctx = ContextManager.GetManager(DataAccessL2S.Database.Security))
{
int ret = ctx.DataContext.UserApplication_UpdateLastLogon(UserApplicationPK, LastLogin, LastLoginInfo);
Result = (ret == 0);
}
}

#endregion
}
}

Thanks in advance
Russ

JonnyBee replied on Tuesday, February 02, 2010

Hi Russ,

Pre Csla 4.0 and when using ObjectFactory the DataPortal.Execute will actually call the Update method on the factory class.

This has been rewritten for CSLA 4.0 preview 2 to call the Execute method in ObjectFactory.
http://lhotka.net/cslabugs/edit_bug.aspx?id=560

Russ replied on Tuesday, February 02, 2010

Thanks JonnyBee,

I added the a DataPortal_Update method but the breakpoints were still not being hit. I also noticed that the intellisense for the override keyword did not offer up a DataPortal_Update method to override for the CommandBase.

So, I went back to Rocky's Silverlight video series and skimmed through it again. I found the answer in video number 5 at 44 minutes in. My mobile object did not have a parameterless public constructor that is required by the mobile formattter and my properties needed to be changed to the following format:

private static PropertyInfo UserApplicationPKProperty =
RegisterProperty(typeof(UpdateLastLogonCO), new PropertyInfo("UserApplicationPK"));
public int UserApplicationPK
{
get { return ReadProperty(UserApplicationPKProperty); }
set { LoadProperty(UserApplicationPKProperty, value); }
}

Now when I run it my breakpoint in my DataPortal_Execute() method is being hit!

Russ

P.S. I just noticed that when I paste code into this forum it removes the greater than and less than characters and the content between them. So please note that my PropertyInfos are strongly typed as int.

Copyright (c) Marimer LLC