title: Enterprise Library Validation Block for Nullable<DateTime>
body: <p>I am playing around with The Enterprise Library Validation Block. I have a class from a Linq To Entities edmx file I am using in an MVC project. I want to make sure that a Nullable DateTime is always later than a DateTime. I am using attributes in a metadata class to create a default ruleset. When attempting to validate with the PropertyComparisonValidator I get the Exception: </p>
  
  <blockquote>
    <p>A validation attribute of type PropertyComparisonValidatorAttribute cannot be used to validate values.</p>
  </blockquote>
  
  <p>I theorized that I couldn't compare a Nullable type to a struct so I wrote the custom class below specifcally to get around that perceived problem. Still I get this exception: </p>
  
  <blockquote>
    <p>A validation attribute of type NullableDateComparisonValidatorAttribute cannot be used to validate values.</p>
  </blockquote>
  
  <p>Next I attempted Self Validation from the Enterprise Library and that failed to fire when validating. I am at a temporary standstill until I get this figured out. Please suggest a solution\workaround that isn't too ugly.</p>
  
  <pre><code>using System;
  using System.Reflection;
  using Microsoft.Practices.EnterpriseLibrary.Validation;
  using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
  
  namespace IdahoUtility
  {
      public class NullableComparisonValidator&lt;T&gt; : Validator&lt;Nullable&lt;T&gt;&gt;
          where T: struct, IComparable
      {
          protected string propertyToCompare { get; set; }
          protected ComparisonOperator comparisionOperator { get; set; }
          protected T TargetProperty(object currentTarget)
          {
              if (null == currentTarget)
              {
                  throw new ArgumentNullException("currentTarget");
              }
  
              Type t = currentTarget.GetType();
              PropertyInfo pInfo = t.GetProperty(propertyToCompare);
              object oValue = pInfo.GetValue(currentTarget, null);
  
              if (oValue.GetType() != typeof(T))
              {
                  throw new InvalidOperationException(string.Format("Property compared must be a {0}!",typeof(T)));
              }
  
              return (T)oValue;
          }
          public NullableComparisonValidator(string PropertyToCompare, ComparisonOperator cmpOp)
              :base(null,null)
          {
              if (string.IsNullOrWhiteSpace(PropertyToCompare))
              {
                  throw new ArgumentException("PropertyToCompare is Invalid!", "PropertyToCompare");
              }
              propertyToCompare = PropertyToCompare;
              comparisionOperator = cmpOp;
          }
          protected override void DoValidate(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              // ignore nulls
              if (null == objectToValidate)
              {
                  return;
              }
  
              switch (comparisionOperator)
              {
                  case ComparisonOperator.Equal:
                      DoValidateEqual(objectToValidate, currentTarget, key, validationResults);
                      break;
                  case ComparisonOperator.GreaterThan:
                      DoValidateGreaterThan(objectToValidate, currentTarget, key, validationResults);
                      break;
                  case ComparisonOperator.GreaterThanEqual:
                      DoValidateGreaterThanEqual(objectToValidate, currentTarget, key, validationResults);
                      break;
                  case ComparisonOperator.LessThan:
                      DoValidateLessThan(objectToValidate, currentTarget, key, validationResults);
                      break;
                  case ComparisonOperator.LessThanEqual:
                      DoValidateLessThanEqual(objectToValidate, currentTarget, key, validationResults);
                      break;
                  case ComparisonOperator.NotEqual:
                      DoValidateNotEqual(objectToValidate, currentTarget, key, validationResults);
                      break;             
              }
          }
  
          private void DoValidateLessThanEqual(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) &gt; 0)
              {
                  LogValidationResult(validationResults, string.Format("Should be less than or equal to {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          private void DoValidateLessThan(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) &gt;= 0)
              {
                  LogValidationResult(validationResults, string.Format("Should be less than {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          private void DoValidateGreaterThanEqual(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) &lt; 0)
              {
                  LogValidationResult(validationResults, string.Format("Should be greater than or equal {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          private void DoValidateGreaterThan(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) &lt;= 0)
              {
                  LogValidationResult(validationResults, string.Format("Should be greater than {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          private void DoValidateEqual(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) != 0)
              {
                  LogValidationResult(validationResults, string.Format("Should be equal to {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          private void DoValidateNotEqual(Nullable&lt;T&gt; objectToValidate, object currentTarget, string key, ValidationResults validationResults)
          {
              if (objectToValidate.Value.CompareTo(TargetProperty(currentTarget)) == 0)
              {
                  LogValidationResult(validationResults, string.Format("Should not be equal to {0}!", propertyToCompare), currentTarget, key);
              }
          }
  
          protected override string DefaultMessageTemplate
          {
              get { return "{0}"; }
          }
      }
  }
  </code></pre>