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):
static bool RegExMatch(object target, RuleArgs e)public
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))
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))
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.
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
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
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
Copyright (c) Marimer LLC