MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

GetBrokenRules & Attributes #270

Closed dglasses closed 8 years ago

dglasses commented 8 years ago

Hello

I have required attribute on a column of a model.

I am overriding AddBusinessRules method and adding a custom rule. When I call Mode.Save in my viewmodel and get the list of broken rules, I don't get required attribute as a broken rule, only the custom rule is listed.

But, If I remove the override or AddBusinessRules, I get the required attribute as broken rule.

Is it by design or I am missing something?

Thanks

lmsantin commented 8 years ago

Are calling the AddBusinessRules method in your base class?

        protected override void AddBusinessRules()
        {
            base.AddBusinessRules();
            //your rules here
        }
dglasses commented 8 years ago

Yes.

lmsantin commented 8 years ago

Are you calling the base class DataPortal_Create method when you create your object?

        protected override void DataPortal_Create()
        {
            using (BypassPropertyChecks)
            {

            }
            base.DataPortal_Create();
        }
dglasses commented 8 years ago

No, I was not calling base.DataPortal_Create(). I added it and I still do not get the required column attributes using GetBrokenRules() method.

lmsantin commented 8 years ago

Let's debug your code:

        protected override void DataPortal_Create()
        {
            using (BypassPropertyChecks)
            {

            }
            base.DataPortal_Create();
            //Add the following line an set a breakpoint on it
           var myObject = this;
        }

When you get to the breakpoint, check "myObject", it should have all the rules broken. The rules will be broken till you assign a valid value to the property.

dglasses commented 8 years ago

Is it protected override or private void?

dglasses commented 8 years ago

I only get those broken rules which I added in AddBusinessRules, the Required attributes are not listed in the collection.

lmsantin commented 8 years ago

Could you put one required property here?

dglasses commented 8 years ago

[Column] [Required] public string Fax { get; set; }

lmsantin commented 8 years ago

-In your DataPortal_Create(), check the value myObject.Fax before exiting that method. -Check the Mode.Fax value before call Mode.Save

jonnybee commented 8 years ago

This may be the behavior of the custom rule and caused by the custom rule making a short circuit of the rule processing.

Could you post the custom rule here?

dglasses commented 8 years ago

internal class ValidOrder:BusinessRule { protected override void Execute(RuleContext context) { //TODO: these rules are fictitious and they are subject to further developments. var target = (Order)context.Target;

        if(string.Equals(target.Code,target.Description,StringComparison.CurrentCultureIgnoreCase))
        {
            context.AddErrorResult("Example:code and description cannot be the same!");
        }
    }
}
dglasses commented 8 years ago

The value of fax is null in the DataPortal_Create and before the Model.save

jonnybee commented 8 years ago

So, the custom rule is an object rule?

If so it will only be executed when you call BusinessRules.CheckRules or BusinessRules.CheckObjectRules. It will not be executed when the property is changed as the Required rule will be.

lmsantin commented 8 years ago

I see, the property is working fine. Fax is a string so it's null in the Create and before calling Save because you haven't assign a value to it.

Is your custom rule a per-type rule?

jonnybee commented 8 years ago

Could you post a small sample project that show your issue?

That would make it a lot easier to locate the problem.

Could you also provide a description of what you are expecting in terms of behavior/user experience and what type of application you are building? Also which version of CSLA are you using?

A quick look at your code shows several possible causes.

  1. You are not using managed properties in the CSLA style.
  2. This will not make the BO raise PropertyHasChanged event that is required for the RuleEngine to know that this filed has changed and to rerun validation rules for this property.
  3. You use a mix of ObjectRules and PropertyRules that may run at different triggers og only when called from your code.
dglasses commented 8 years ago

Hello Jonnybee

  1. Not sure what you mean by CSLA style managed properties ( I added GetProperty(FaxProperty) and SetProperty(FaxProperty, value). Still did get see the failed rule in collection returned by GetBrokenRules method.
  2. The ux is very simple. a. WPF (prisim module) has order control and orderviewmodel. b. Order control has save button. c. When save button is called I call BeginRefresh(callback => Models.Order.CreateNewOrder(callback)) d. Then, I call Model.ApplyEdit and check if Model.IsValid and call Model.Save c. If Model is not valid. Following code: var brokenRules = Model.GetBrokenRules();

If I remove protected override void AddBusinessRules(), then I can see the properties marked with "Required" attribute in the collection returned GetBrokenRules(). But, as soon as I add AddBusinessRules method, I do not see the properties marked with "Required" attribute.

dglasses commented 8 years ago

Hello Everyone

I was able to resolve the. I did not realize that the custom rule was being added to a new ruleset and I was not changing the ruleset back to default.

Thanks