Execute command object from client-side rule

Execute command object from client-side rule

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


emadalsous posted on Friday, October 15, 2010

hi, Rocky

i have scenario where i have validationrule which runs command on server side how can i let the client bin execute it

on server side here is my code :

    private class RuleClass: BusinessRule
        {
            protected override void Execute(RuleContext context)// bool UniqueCashName<T>(T target, RuleArgs e) where T : Cash
            {
                IsAsync = true;
                var target = (SomeClass)context.Target;
                if (target.IsNew && ExsistCashRefName.IsExsist(target.ReadProperty(NameProperty)))
                {
                    context.AddErrorResult("This name is allready exsist");
                }


            }
        }

and the ExsistCashRefName is command where it has to connect with the database

how should the command or the rule look like to request the server

RockfordLhotka replied on Saturday, October 16, 2010

On a .NET client you can just use this code, the rule will run synchronously and the command will execute. It should work fine because the data portal will make it "just work".

On a SL client this won't work without change, because the command will execute asynchronously. That means your rule needs to be an async rule so it can invoke the async command object and process the result when the command completes.

That's not terribly hard to do, and I have a blog post that shows how to implement an async rule.

emadalsous replied on Saturday, October 16, 2010

Hello Rocky, Thanks for your reply. i have looked at the blog you had put about async validation rules

and i did as i found in the blog but there's little problem , that i know that there's something missing in my code

iam sure that i have missed something, i would appreciate if you check the following code for me .

in .NET client ihad this code :

 

 

 

 

 

 

 

 

private class UniqueCurrency : BusinessRule 

{

 

 

 

public UniqueCurrency(PropertyInfo<string> primaryProperty, PropertyInfo<string> Affectedproperty)

{

InputProperties =

 

new List<Csla.Core.IPropertyInfo > { primaryProperty };

AffectedProperties.Add(Affectedproperty);

}

 

 

 

protected override void Execute(RuleContext context)

// bool UniqueCurrencyName<T>(T target, RuleArgs e) where T : Currency

{

 

 

 

var target = (Currency )context.Target;

 

 

 

if (target.IsNew && ExsistCurrncyName .IsExsist(target.ReadProperty(NameProperty)))

{

context.AddErrorResult(

 

"This name is allready exsist" );

 

and to Async the rule in SL client side i have put the following code :

 

private class UniqueCurrency : BusinessRule

{

public UniqueCurrency(PropertyInfo<string> primaryProperty, PropertyInfo<string> Affectedproperty)

{

IsAsync=true;

InputProperties = new List<Csla.Core.IPropertyInfo> { primaryProperty };

AffectedProperties.Add(Affectedproperty);

}

 

protected override void Execute(RuleContext context)

{

var bw = new System.ComponentModel.BackgroundWorker();

 

bw.DoWork += (o, e) =>

{

var value = (string)context.InputPropertyValues[InputProperties[0]];

context.AddOutValue(InputProperties[0], value.ToUpper());

};

bw.RunWorkerCompleted += (o, e) =>

{

if (e.Error != null)

context.AddErrorResult(e.Error.Message);

context.Complete();

};

bw.RunWorkerAsync();

}

}

well , what i think is happeining that the rule doesnt check any thing from the server

one more last thing do i have to change any thing in the command that the rule execute on server-side

 

 

RockfordLhotka replied on Saturday, October 16, 2010

You wouldn't use the BackgroundWorker to call a command object. I used the BW in my blog post just to illustrate the structure of an Execute method that calls some async operation. BW is an async operation, and so is a command object.

So your Execute method would contain something like this:

var cmd = new MyCommand();
DataPortal.BeginExecute<MyCommand>(cmd, (o, e) =>
{
  if (e.Error != null)
    context.AddErrorResult(e.Error.Message);
  else
    if (e.Object.Exists)
      context.AddErrorResult("Value exists");
  context.Complete();
});

The whole idea is that your Execute method invokes some async operation (in this case the BeginExecute) and handles the callback to determine the result, which is then provided back to the object through the context parameter.

emadalsous replied on Sunday, October 17, 2010

Hello Rocky, thank you for your response i have applied the code which you have post

and every thing worked fine the command is executing but there's a little issue .

when the command gives when i add new object the command executed right for only one time

and the second time it gives me the following error :

No parametless constructor defined for the object

i know that there's no constructor without parameters but in my case ihave

the constructor passing values, then i added constructor without parameters

but when i  did so every thing worked fine but the error that the fields in my command object becase without values

because the constructor with parameters wasnt used on .Net client it's only called on SL client-side

and the Execute method doest has query which became with where statement with null value so the result is invalid

 

Copyright (c) Marimer LLC