Collection Validation

Some business rules need us to loop through all items within the same list, such as exist, duplication, and period overlap stuff.

Rocky says those validation has to build on entity level, not on the collection level. Yes, you are not directly change the property in collection object, instead, you change the item.

Here is my code sample,


        public void AddCustomRules()
        {
            ValidationRules.AddRule(STDateGTENDDate, "EffectiveDate");
            ValidationRules.AddRule(STDateGTENDDate, "ExpiredDate");
                ValidationRules.AddRule(PeriodNotOverLap, "EffectiveDate");
                ValidationRules.AddRule(PeriodNotOverLap, "ExpiredDate");
        }

        static bool PeriodNotOverLap(object target, Csla.Validation.RuleArgs e)
        {
            var current = (StakeholderAddressBO) target;
            if (current.Parent == null) return true;
            e.Description = "Period should not be overlap.";
                foreach (var s in (StakeholderAddressBOCollection) current.Parent)
                {
                    if ((s.EffectiveDate > current.EffectiveDate &&
                         s.EffectiveDate < current.ExpiredDate) ||
                        s.ExpiredDate < current.ExpiredDate &&
                        s.ExpiredDate > current.EffectiveDate)
                        return false;
                }
            return true;
        }

It works OK. My UI can get this nice error indicator when two address periods have overlap. But, if I change the other row to remove the overlap, instead of the “current trouble maker”, then current one’s error indicator won’t go away even I don’t have any overlap at all.

This is not right. I tried to fix it but there are many restrictions.

First, I can’t call another loop through in my ruleHandler: PeriodNotOverLap. because this will trigger the same validation ruleHandler process, it then become a dead loop.

A nicer solution should be, do a loop through all the sibling items, check brokenrule, if this brokenrule is same as the one I am currently running, then remove it, the isvalid should automatically be back.

But, again, CSLA won’t allow me to remove Brokenrule from BrokenruleCollection object, it’s protected!

I had to do this outside check rule loop to fix this problem, manually by a button click.


        private void ValidateAddressList()
        {

            foreach (var a in _organization.StakeholderAddressBOCollection)
            {
                if (!a.IsValid)
                {

                     // a warpper to ValidationRules.CheckRules();
                    a.CheckRules();
                 }
            }

            stakeholderAddressBOCollectionDataGridView.Refresh();
        }

Today, I got a better solution, override IsValid in myBO:

        public override bool IsValid
        {
            get
            {

                foreach (var v in ValidationRules.GetBrokenRules())
                {
                     if (v.RuleName.Contains("PeriodNotOverLap"))
                     {
                         if (v.Severity == RuleSeverity.Error)
                         {
                             if (PeriodNotOverLap(this, null))
                             {
                                 return ValidationRules.GetBrokenRules().ErrorCount -
                                 ValidationRules.GetBrokenRules().Count(x => x.RuleName.Contains("PeriodNotOverLap")) == 0;
                             }
                         }
                     }

                }

                return ValidationRules.GetBrokenRules().ErrorCount == 0;

            }
        }

Surprise, this also works for delete!? Why, maybe delete also cause a re-run of each validation rule?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s