CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

ArgumentNullException in CommonRules.RegExMatch()

rated by 0 users
This post has 12 Replies | 4 Followers

Not Ranked
Posts 2
cstaley Posted: Mon, Jan 22 2007 2:07 PM

I've modified the CSLA.Contib templates to generate nullable value types on columns that allow nulls.  As a result, I'm running into problems with the RegExMatch() method in the Csla.Validation.CommonRules class when new CSLA objects are created.  The problem is that a null value is being validated, and the RegEx.IsMatch() method doesn't like null values being passed in (i.e. it throws a ArgumentNullException).

It seems like the RegExMatch() method should handle this situation more gracefully.  A null value should simply cause the rule to break, rather than throw an exception.  Afterall, a null value couldn't possibly match the regular expression, could it?

To handle this, I've modified the RegExMatch() method as follows (changes in bold):

public static bool RegExMatch(object target, RuleArgs e)
{
   Regex rx = ((RegExRuleArgs
)e).RegEx;
   string propertyValue = Utilities.CallByName(target, e.PropertyName, CallType.Get) as string
;
   if (propertyValue == null
|| !rx.IsMatch(propertyValue))
   {
      e.Description =
String.Format(Resources
.RegExMatchRule, e.PropertyName);
      return false
;
   }
   else
      return true
;
}

Top 10 Contributor
Posts 9,270
I've added this request to my to-do list for future versions of the framework.

Rocky

Not Ranked
Posts 2
LEEG replied on Thu, Mar 1 2007 3:55 PM

I ran into the same situation.  The one difference I would make is that a null or empty string would return true.  If the value shouldn't be null or an empty string then you would use the CommonRules.StringRequired rule as well.

So instead of the following:

if (propertyValue == null || !rx.IsMatch(propertyValue))

you would have:

if (!String.IsNullOrEmpty(propertyValue) && !rx.IsMatch(propertyValue))

 

Top 10 Contributor
Posts 9,270

My goal with RegEx is to allow anything that can be evaluated to be evaluated.

 

Your regex might reject or accept an empty string – I can’t make that judgment in code without restricting what can be expressed in the regex itself.

 

So the only real debate here, and I agree that there is one, is what to do about null values?

 

There are three answers:

 

1.       A null is an automatic True result

2.       A null is an automatic False result

3.       A null is converted to string.Empty and the regex runs

 

I’m not entirely sure which is the right answer overall, but thinking about it right now I lean toward #3.

 

Rocky

 

From: LEEG [mailto:cslanet@lhotka.net]
Sent: Thursday, March 01, 2007 3:56 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] ArgumentNullException in CommonRules.RegExMatch()

 

I ran into the same situation.  The one difference I would make is that a null or empty string would return true.  If the value shouldn't be null or an empty string then you would use the CommonRules.StringRequired rule as well.

So instead of the following:

if (propertyValue == null || !rx.IsMatch(propertyValue))

you would have:

if (!String.IsNullOrEmpty(propertyValue) && !rx.IsMatch(propertyValue))

 



Rocky

Not Ranked
Posts 2
cstaley replied on Thu, Mar 8 2007 10:43 AM
Given the three options, I would argue for #2 by the process of elimination.

#1 is out because, as I originally posted at the start of the thread, passing in a null value to RegEx.IsMatch() will throw an exception.  Therefore, if you can't definitively say, "Yes, this value matches the regular expression," then you should never return true.

#3 should be eliminated for the same reason, but with the additional aggravating circumstance wherein a comparison of the actual value is never being made.  Additionally, since null and empty string can have different meanings, the method could effectively be misunderstanding the property's value, especially if the regular expression accepts empty strings.
Top 10 Contributor
Posts 9,270

For fun I implemented 1 and 2 - allowing you to specify the result of a null. You can see the code in svn (C#) if you'd like.

I think I might actually support 3 using a similar technique - that wouldn't be terribly hard to do.

Rocky

Top 500 Contributor
Posts 35
Rocky,

i am having an bo say employee. which do have up an required field i.e companyid (to which company he belongs) now i wnat to implement this in my bo .
that is in validation rules there is something called stringrequired , but this is going to be an int filed so doesnt there do exist something like intrequired .

another thing . coming up to the same scenario ,assuming the same business object employee , the companyid (which is to be populated via another namevalue list object) is the foreign key in database , but the datamapper maps it and returns 0 if null so to overcome this , what would be the best approach as if to handle null values and pss the null values back to database . like this should go null rather then 0 to database and come 0 rather then null from database as all the namevalue lsit objects do contain a default item with index 0 so i dont thing that could b a prob .

thanks
govind
Top 500 Contributor
Posts 35
Rocky,

I am using csla 3.0
I am working on to integrate validatino application blocks(VAB), DAAB, and caching application blocks with csla .

firstly moving with VAB here are the steps i had followed.
1. got the refrence of VAB,Common , from application blocks
2. created a class VAB with the following definition
 public class VABRules
    {
        public class VABRuleArgs : RuleArgs
        {
            private string _ruleset;

            public string Ruleset
            {
                get { return _ruleset; }
            }


            public VABRuleArgs(string propertyName)
                : this(propertyName, null)
            {
            }

            public VABRuleArgs(string propertyName, string ruleset)
                : base(propertyName)
            {
                _ruleset = ruleset;
            }
        }

        public static bool VABValid<T>(object target, RuleArgs e)
        {
            Validator<T> validator = ValidationFactory.CreateValidator<T>(((VABRuleArgs)e).Ruleset);

            if (validator == null)
                return true;

            ValidationResults results = validator.Validate(target);

            if (results == null)
                return true;

            foreach (ValidationResult result in results)
            {
                if (result.Key == e.PropertyName)
                {
                    e.Description = result.Message;
                    return false;
                }
            }

            return true;
        }
    }

now on csla object say currency

for one of my property .
  [NotNullValidator]
        [StringLengthValidator(1, 50, MessageTemplate = "Currency code can not be empty")]
   
        public string sCode
        {
            get
            {
                CanReadProperty(true);
                return _Code;
            }
            set
            {
                CanWriteProperty(true);
                if (value == null) value = string.Empty;
                if (_Code != value)
                {
                    _Code = value;
                    PropertyHasChanged();
                }
            }
        }

and finally in the

  protected override void AddBusinessRules()
        {
                ValidationRules.AddRule(VABRules.VABValid<Currency>, new VABRules.VABRuleArgs("sCode","RuleSetCurrency"));

        }


but this is not getting called and not firing validation . on contrary done with csla.validation it is working fine .

coould you please shed some light on the issue why i am not able to get the validation check .

thanks
govind
Top 10 Contributor
Posts 9,270

A “required integer” field probably just means the value must be >0 right? So you can use the MinValue rule, or the RegExMatch rule.

 

To deal with null values that should flow from the UI to/from the database, you should look at Nullable(Of T). In C# the compiler implements some syntactic sugar around Nullable<T> to give you things like int? and bool? which are nullable values.

 

Rocky

 

 

From: jhoojharsinghyadav [mailto:cslanet@lhotka.net]
Sent: Friday, September 21, 2007 7:07 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] ArgumentNullException in CommonRules.RegExMatch()

 

Rocky,

i am having an bo say employee. which do have up an required field i.e companyid (to which company he belongs) now i wnat to implement this in my bo .
that is in validation rules there is something called stringrequired , but this is going to be an int filed so doesnt there do exist something like intrequired .

another thing . coming up to the same scenario ,assuming the same business object employee , the companyid (which is to be populated via another namevalue list object) is the foreign key in database , but the datamapper maps it and returns 0 if null so to overcome this , what would be the best approach as if to handle null values and pss the null values back to database . like this should go null rather then 0 to database and come 0 rather then null from database as all the namevalue lsit objects do contain a default item with index 0 so i dont thing that could b a prob .

thanks
govind


Rocky

Top 10 Contributor
Posts 9,270

I don’t know.

 

One possible issue: you aren’t using the NoInlining attribute in your property declaration, but you are using the CanReadProperty(), CanWriteProperty() and PropertyHasChanged() overloads that only reliable work if you DO use the NoInlining property.

 

Rocky

 

 

From: jhoojharsinghyadav [mailto:cslanet@lhotka.net]
Sent: Friday, September 21, 2007 7:23 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] ArgumentNullException in CommonRules.RegExMatch()

 

Rocky,

I am using csla 3.0
I am working on to integrate validatino application blocks(VAB), DAAB, and caching application blocks with csla .

firstly moving with VAB here are the steps i had followed.
1. got the refrence of VAB,Common , from application blocks
2. created a class VAB with the following definition
 public class VABRules
    {
        public class VABRuleArgs : RuleArgs
        {
            private string _ruleset;

            public string Ruleset
            {
                get { return _ruleset; }
            }


&nbs p;           public VABRuleArgs(string propertyName)
                : this(propertyName, null)
            {
            }

            public VABRuleArgs(string propertyName, string ruleset)
                : base(propertyName)
            {
                _ruleset = ruleset;
            }
        }

        public static bool V ABValid<T>(object target, RuleArgs e)
        {
            Validator<T> validator = ValidationFactory.CreateValidator<T>(((VABRuleArgs)e).Ruleset);

            if (validator == null)
                return true;

            ValidationResults results = validator.Validate(target);

            if (results == null)
                return true;

            foreach (ValidationResult result in results)
            {
                if (result.Key == e.PropertyName)
                {
                    e.Description = result.Message;
                    return false;
                }
            }

            return true;
        }
    }

now on csla object say currency

for one of my property .
  [NotNullValidator]
        [StringLe ngthValidator(1, 50, MessageTemplate = "Currency code can not be empty")]
   
        public string sCode
        {
            get
            {
                CanReadProperty(true);
                return _Code;
            }
            set
            {
                CanWriteProperty(true);
           &n bsp;    if (value == null) value = string.Empty;
                if (_Code != value)
                {
                    _Code = value;
                    PropertyHasChanged();
                }
            }
        }

and finally in the

  protected override void AddBusinessRules()
        {
                ValidationRules.AddRule(VABRules.VABValid<Currency>, new VABRules.VABRuleArgs("sCode","RuleSetCurrency"));

        }


but this is not getting called and not firing validation . on contrary done with csla.validation it is working fine .

coould you please shed some light on the issue why i am not able to get the validation check .

thanks
govind


Rocky

Top 500 Contributor
Posts 35
hmm ,

seems as if i had to use the csla contrib library instead of validation application block .
but the only mess i m facing with is that i am nto able to throw custom messages if using the commonrules.
thats why i opted for validation blocks .

is there any workaround to get the custom message s.

1 most importatnt thing is that while being up in insert mode , say for example i do get up the validation rule exception the whole of the dataview is cleared mean the object is recreated fresh which i want to avoid mean i want that if error is there then the object does not get clear but instead stops processing if something is wrong there if with the data being retained (which is correct)

how to achieve this .

thanks
govind

Top 10 Contributor
Posts 9,270

If you don’t like the messages returned from the rule methods in CommonRules then you can create your own rule methods – create your own common rules library within your application. This is the whole reason the architecture is so open and delegate-based, is to allow you to create your own rule methods to meet your needs.

 

I don’t understand what you are saying about the grid, sorry.

 

Rocky

 

From: jhoojharsinghyadav [mailto:cslanet@lhotka.net]
Sent: Friday, September 21, 2007 8:42 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: ArgumentNullException in CommonRules.RegExMatch()

 

hmm ,

seems as if i had to use the csla contrib library instead of validation application block .
but the only mess i m facing with is that i am nto able to throw custom messages if using the commonrules.
thats why i opted for validation blocks .

is there any workaround to get the custom message s.

1 most importatnt thing is that while being up in insert mode , say for example i do get up the validation rule exception the whole of the dataview is cleared mean the object is recreated fresh which i want to avoid mean i want that if error is there then the object does not get clear but instead stops processing if something is wrong there if with the data being retained (which is correct)

how to achieve this .

thanks
govind



Rocky

Top 500 Contributor
Posts 35
Rocky,

i am working up with  a scenario .
suppose my users comes up with an insert mode in detail view and then successfully inserts the object .
now he wants to do more insertions like , go on inserting .till he wishes.
not getting over it .

thanks
govind
Page 1 of 1 (13 items) | RSS

Copyright (c) 2006-2010 Marimer LLC. All rights reserved.
Email admin@lhotka.net for support.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems