using System; using Csla.Properties; using System.Text.RegularExpressions; using System.Reflection; namespace Csla.Validation { /// /// Implements common business rules. /// public static class CommonRules { #region StringRequired /// /// Rule ensuring a string value contains one or more /// characters. /// /// Object containing the data to validate /// Arguments parameter specifying the name of the string /// property to validate /// if the rule is broken /// /// This implementation uses late binding, and will only work /// against string property values. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] public static bool StringRequired(object target, RuleArgs e) { string value = (string)Utilities.CallByName( target, e.PropertyName, CallType.Get); if (string.IsNullOrEmpty(value)) { e.Description = string.Format(Resources.StringRequiredRule, e.PropertyName); return false; } return true; } #endregion #region StringMaxLength /// /// Rule ensuring a string value doesn't exceed /// a specified length. /// /// Object containing the data to validate /// Arguments parameter specifying the name of the string /// property to validate /// if the rule is broken /// /// This implementation uses late binding, and will only work /// against string property values. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] public static bool StringMaxLength( object target, RuleArgs e) { int max = ((MaxLengthRuleArgs)e).MaxLength; string value = (string)Utilities.CallByName( target, e.PropertyName, CallType.Get); if (!String.IsNullOrEmpty(value) && (value.Length > max)) { e.Description = String.Format( Resources.StringMaxLengthRule, e.PropertyName, max.ToString()); return false; } return true; } /// /// Custom object required by the /// rule method. /// public class MaxLengthRuleArgs : RuleArgs { private int _maxLength; /// /// Get the max length for the string. /// public int MaxLength { get { return _maxLength; } } /// /// Create a new object. /// /// Name of the property to validate. /// Max length of characters allowed. public MaxLengthRuleArgs( string propertyName, int maxLength) : base(propertyName) { _maxLength = maxLength; } /// /// Return a string representation of the object. /// public override string ToString() { return base.ToString() + "?maxLength=" + _maxLength.ToString(); } } #endregion #region IntegerMaxValue /// /// Rule ensuring an integer value doesn't exceed /// a specified value. /// /// Object containing the data to validate. /// Arguments parameter specifying the name of the /// property to validate. /// if the rule is broken. public static bool IntegerMaxValue(object target, RuleArgs e) { int max = ((IntegerMaxValueRuleArgs)e).MaxValue; int value = (int)Utilities.CallByName(target, e.PropertyName, CallType.Get); if (value > max) { e.Description = String.Format(Resources.MaxValueRule, e.PropertyName, max.ToString()); return false; } return true; } /// /// Custom object required by the /// rule method. /// public class IntegerMaxValueRuleArgs : RuleArgs { private int _maxValue; /// /// Get the max value for the property. /// public int MaxValue { get { return _maxValue; } } /// /// Create a new object. /// /// Name of the property. /// Maximum allowed value for the property. public IntegerMaxValueRuleArgs(string propertyName, int maxValue) : base(propertyName) { _maxValue = maxValue; } /// /// Return a string representation of the object. /// public override string ToString() { return base.ToString() + "?maxValue=" + _maxValue.ToString(); } } #endregion #region IntegerMinValue /// /// Rule ensuring an integer value doesn't go below /// a specified value. /// /// Object containing the data to validate. /// Arguments parameter specifying the name of the /// property to validate. /// if the rule is broken. public static bool IntegerMinValue(object target, RuleArgs e) { int min = ((IntegerMinValueRuleArgs)e).MinValue; int value = (int)Utilities.CallByName(target, e.PropertyName, CallType.Get); if (value < min) { e.Description = String.Format(Resources.MinValueRule, e.PropertyName, min.ToString()); return false; } return true; } /// /// Custom object required by the /// rule method. /// public class IntegerMinValueRuleArgs : RuleArgs { private int _minValue; /// /// Get the min value for the property. /// public int MinValue { get { return _minValue; } } /// /// Create a new object. /// /// Name of the property. /// Minimum allowed value for the property. public IntegerMinValueRuleArgs(string propertyName, int minValue) : base(propertyName) { _minValue = minValue; } /// /// Return a string representation of the object. /// public override string ToString() { return base.ToString() + "?minValue=" + _minValue.ToString(); } } #endregion #region MaxValue /// /// Rule ensuring that a numeric value /// doesn't exceed a specified maximum. /// /// Type of the property to validate. /// Object containing value to validate. /// Arguments variable specifying the /// name of the property to validate, along with the max /// allowed value. public static bool MaxValue(object target, RuleArgs e) where T : IComparable { PropertyInfo pi = target.GetType().GetProperty(e.PropertyName); T value = (T)pi.GetValue(target, null); T max = ((MaxValueRuleArgs)e).MaxValue; int result = value.CompareTo(max); if (result >= 1) { e.Description = string.Format(Resources.MaxValueRule, e.PropertyName, max.ToString()); return false; } else return true; } /// /// Custom object required by the /// rule method. /// /// Type of the property to validate. public class MaxValueRuleArgs : RuleArgs { T _maxValue = default(T); /// /// Get the max value for the property. /// public T MaxValue { get { return _maxValue; } } /// /// Create a new object. /// /// Name of the property. /// Maximum allowed value for the property. public MaxValueRuleArgs(string propertyName, T maxValue) : base(propertyName) { _maxValue = maxValue; } /// /// Returns a string representation of the object. /// public override string ToString() { return base.ToString() + "?maxValue=" + _maxValue.ToString(); } } #endregion #region MinValue /// /// Rule ensuring that a numeric value /// doesn't exceed a specified minimum. /// /// Type of the property to validate. /// Object containing value to validate. /// Arguments variable specifying the /// name of the property to validate, along with the min /// allowed value. public static bool MinValue(object target, RuleArgs e) where T : IComparable { PropertyInfo pi = target.GetType().GetProperty(e.PropertyName); T value = (T)pi.GetValue(target, null); T min = ((MinValueRuleArgs)e).MinValue; int result = value.CompareTo(min); if (result <= -1) { e.Description = string.Format(Resources.MinValueRule, e.PropertyName, min.ToString()); return false; } else return true; } /// /// Custom object required by the /// rule method. /// /// Type of the property to validate. public class MinValueRuleArgs : RuleArgs { T _minValue = default(T); /// /// Get the min value for the property. /// public T MinValue { get { return _minValue; } } /// /// Create a new object. /// /// Name of the property. /// Minimum allowed value for the property. public MinValueRuleArgs(string propertyName, T minValue) : base(propertyName) { _minValue = minValue; } /// /// Returns a string representation of the object. /// public override string ToString() { return base.ToString() + "?minValue=" + _minValue.ToString(); } } #endregion #region RegEx /// /// Rule that checks to make sure a value /// matches a given regex pattern. /// /// Object containing the data to validate /// RegExRuleArgs parameter specifying the name of the /// property to validate and the regex pattern. /// False if the rule is broken /// /// This implementation uses late binding. /// public static bool RegExMatch(object target, RuleArgs e) { Regex rx = ((RegExRuleArgs)e).RegEx; if (!rx.IsMatch(Utilities.CallByName(target, e.PropertyName, CallType.Get).ToString())) { e.Description = String.Format(Resources.RegExMatchRule, e.PropertyName); return false; } else return true; } /// /// List of built-in regex patterns. /// public enum RegExPatterns { /// /// US Social Security number pattern. /// SSN, /// /// Email address pattern. /// Email } /// /// Custom object required by the /// rule method. /// public class RegExRuleArgs : RuleArgs { Regex _regEx; /// /// The object used to validate /// the property. /// public Regex RegEx { get { return _regEx; } } /// /// Creates a new object. /// /// Name of the property to validate. /// Built-in regex pattern to use. public RegExRuleArgs(string propertyName, RegExPatterns pattern) : base(propertyName) { _regEx = new Regex(GetPattern(pattern)); } /// /// Creates a new object. /// /// Name of the property to validate. /// Custom regex pattern to use. public RegExRuleArgs(string propertyName, string pattern) : base(propertyName) { _regEx = new Regex(pattern); } /// /// Creates a new object. /// /// Name of the property to validate. /// object to use. public RegExRuleArgs(string propertyName, System.Text.RegularExpressions.Regex regEx) : base(propertyName) { _regEx = regEx; } /// f /// Returns a string representation of the object. /// public override string ToString() { return base.ToString() + "?regex=" + _regEx.ToString(); } /// /// Returns the specified built-in regex pattern. /// /// Pattern to return. public static string GetPattern(RegExPatterns pattern) { switch (pattern) { case RegExPatterns.SSN: return @"^\d{3}-\d{2}-\d{4}$"; case RegExPatterns.Email: return @"^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$"; default: return string.Empty; } } } #endregion } }