Pull up CSLA BO’s validation message

By default the CSLA BO’s brokenRulesCollection doesn’t contain child BO’s brokenrules, I tried to create a GetValidationMessages() method in MyBusinessBase class, the difficult I had was to cast and detect the generic type. Thanks to this post, I made it happen by creating an IsDerivedFromGenericType method.

I don’t need to call this:  if (child.GetType().IsSubclassOf(typeof(MyBusinessBase<>)))

Or if (child is MyBusinessBase<>)

Actually those two won’t work. This IsDerivedFromGenericType is handy.

if (IsDerivedFromGenericType(child.GetType(), typeof(MyBusinessBase<>) ) )

But it’s too complex, especially I had to call reflection to  call this GetValidationMessages recursively. Because I don’t know how to do this:

((MyBusinessBase<>)child).GetBOValidataionMessage()

Instead I had to call reflection:

        private string GetBOValidataionMessage(object v)
        {
            // Would be nice if I can cast to MyBusinessBase
            // T is an unknow onject type below, so I had to use reflection to invock method.
//            MyBusinessBase bo = (MyBusinessBase)v;
//            return bo.GetValidationMessage();

            string childValidataionMessage = "";
            // invoke method to get validation message from child BO.
            // kind of recursive call here.
            var flags =
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
            MethodInfo method = v.GetType().GetMethod("GetValidationMessage", flags);

            if (method != null)
            {
                childValidataionMessage = (string)method.Invoke(v, null);

            }
            return childValidataionMessage;
        }

In fact, it could be much easier if I just simply override the BrokenRulesCollection property. (Idea from this post.)

        public override BrokenRulesCollection BrokenRulesCollection
        {
            get
            {
                BrokenRulesCollection brokenRules = BrokenRulesCollection.CreateCollection();
                // Get root broken rules.
                brokenRules.Merge(this.ToString(), base.BrokenRulesCollection);

                foreach (var child in this.FieldManager.GetChildren())
                {
                    if (child is IEnumerable)
                    {
                        foreach (var v in (IEnumerable)child)
                        {
                                if (v is BusinessBase){
                                    brokenRules.Merge(v.ToString(), ((BusinessBase) v).BrokenRulesCollection);
                                }
                        }
                    }
                    else
                    {
                        if (child is BusinessBase)
                        {
                            brokenRules.Merge(child.ToString(), ((BusinessBase)child).BrokenRulesCollection);
                        }
                    }
                }

                return brokenRules;
            }
        }

        // BrokenRule class doesn't have an "Owner" field, which is useful in this kind of
        // multi-level object map to locate the actual error message from.
        // Fortunately, the rulename contains object name, so I can do this stupid string parse here.
        public string ExtractObjectName(string ruleName)
        {
            string result;

            // get namespace
            string spacename = this.GetType().Namespace;

            // get rid of namespace
            result = ruleName.Replace(spacename + ".", "");

            // get rid of everything after the dot
            int start = result.LastIndexOf("//") + 2;
            int end = result.IndexOf(".") ;
            result = result.Substring(start, end - start);

            return result;
        }
        public string GetValidationMessage()
        {
            StringBuilder sb = new StringBuilder();

            foreach (var x in this.BrokenRulesCollection)
            {
                 sb.AppendLine(string.Format("{0}.{1}: {2}", ExtractObjectName(x.RuleName),x.Property,  x.Description));
             }

            return sb.ToString();
        }
Advertisements

One thought on “Pull up CSLA BO’s validation message

  1. Dieting is only good for people who want to have minimal effects on their weight loss journey.

    For starters, water is a solvent and as such, eliminates
    excessive vitamins and minerals. This short article will show you
    how African Mango Plus will help you lose weight without dieting.

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