Friday 26 September 2008

Custom validaton in CSLA.NET

Recently I was assigned to a new project which bases on CSLA.NET framework. One of my first tasks was to extend the validation of some business objects. Unfortunetly the Csla.Validation.CommonRules were not enough in my case since I needed to validate the value of one business object property against the value of another one. Here is sample code that checks whether Range.MaxValue is greater than Range.MinValue:
public class Range : Csla.BusinessBase<Range>
{
//members and properties declaration
private int _minValue = 0;
private int _maxValue = 0;

public int MaxValue { get { (...) } set { (...) } }
public int MinValue { get { (...) } set { (...) } }

(...)

protected override void AddBusinessRules()
{
//Change of MaxValue will cause validation of MinValue as well
ValidationRules.AddDependantProperty("MaxValue", "MinValue");

//prepare parameters for valdiation method
Dictionary<string, object> parameters =
new Dictionary<string, object>(1);
parameters.Add(CustomRules.DATE_TO_COMPARE, "MinRange");
DecoratedRuleArgs args =
new DecoratedRuleArgs("MaxRange", parameters);

//add custom validation rule
ValidationRules.AddRuleRule<Rule>(
CustomRules.DateGreaterThan, args);
}
}

public class CustomRules
{
///
/// Checks whether the property value is DateTime and is greater than
/// value specified in field whose name is passed as the argument
/// called as defined in DATE_TO_COMPARE const.
///

///
/// True if date is greater than the date to compare against.
///

///
/// Thrown when impossible to convert any of both dates to DateTime.
///

public static bool DateGreaterThan<T>(T target, RuleArgs e)
{
DecoratedRuleArgs args = (DecoratedRuleArgs)e;

DateTime lesserDate =
(DateTime)Csla.Utilities.CallByName(target,
(string)args[DATE_TO_COMPARE], CallType.Get);
DateTime greaterDate =
(DateTime)Csla.Utilities.CallByName(target,
e.PropertyName, CallType.Get);

if (lesserDate < greaterDate)
{
// date is valid
return true;
}
else
{
// date is invalid - prepare error message
e.Description = e.PropertyFriendlyName +
" has to be greater than " +
(string)args[DATE_TO_COMPARE];
return false;
}
}

}