DateTimeRangeValidator with DateTimeOffset

Topics: Validation Application Block
Sep 23, 2009 at 2:32 PM

 

Hello,

I've just start using DateTimeOffset instead of DateTime with something like this:

[DateTimeRangeValidator(Utils.MinDateToString, Utils.MaxDateToString)]
public DateTimeOffset StartDate { get; private set; }

where Utils.MinDateToString and Utils.MaxDateToString are const strings declared:

public const string MinDateToString = "1899-01-01T00:00:00";

 

When i validate the class I found the following message with DateTimeRangeValidator:

Message = "Value to validate is not of the expected type: expected System.DateTime but got System.DateTimeOffset instead."

Is there some workaround for using DateTimeOffset?

 

Thanks

 

 

Sep 24, 2009 at 6:23 AM

Hi,

It is because, the DateTimeRangeValidator is meant to validate DateTime data type only. A workaround for this is to implement your RangeValidator which validates a DateTimeOffSet data type. Please try this code:

Note: This code is taken from the DateTimeRangeValidator.

DateTimeOffSetRangeValidator.cs

    public class DateTimeOffSetRangeValidator : RangeValidator<DateTimeOffset>
    {

		public DateTimeOffSetRangeValidator(DateTime upperBound)
			: base(upperBound)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime upperBound, bool negated)
			: base(upperBound, negated)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime lowerBound, DateTime upperBound)
			: base(lowerBound, upperBound)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime lowerBound, DateTime upperBound, bool negated)
			: base(lowerBound, upperBound, negated)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime lowerBound, RangeBoundaryType lowerBoundType,
			DateTime upperBound, RangeBoundaryType upperBoundType)
			: base(lowerBound, lowerBoundType, upperBound, upperBoundType)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime lowerBound, RangeBoundaryType lowerBoundType,
			DateTime upperBound, RangeBoundaryType upperBoundType, bool negated)
			: base(lowerBound, lowerBoundType, upperBound, upperBoundType, negated)
		{ }

		
		public DateTimeOffSetRangeValidator(DateTime lowerBound, RangeBoundaryType lowerBoundType,
			DateTime upperBound, RangeBoundaryType upperBoundType,
			string messageTemplate)
			: base(lowerBound, lowerBoundType, upperBound, upperBoundType, messageTemplate)
		{ }

		
        public DateTimeOffSetRangeValidator(DateTime lowerBound, RangeBoundaryType lowerBoundType,
			DateTime upperBound, RangeBoundaryType upperBoundType,
			string messageTemplate, bool negated)
			: base(lowerBound, lowerBoundType, upperBound, upperBoundType, messageTemplate, negated)
		{ }
    }

 

DateTimeOffSetRangeValidatorAttribute.cs

 

    [AttributeUsage(AttributeTargets.Property
    | AttributeTargets.Field
    | AttributeTargets.Method
    | AttributeTargets.Parameter,
    AllowMultiple = true,
    Inherited = false)]
    public class DateTimeOffSetRangeValidatorAttribute : ValueValidatorAttribute
    {
        private DateTime lowerBound;
		private RangeBoundaryType lowerBoundType;
		private DateTime upperBound;
		private RangeBoundaryType upperBoundType;

		public DateTimeOffSetRangeValidatorAttribute(string upperBound)
			: this(ConvertToISO8601Date(upperBound))
		{ }

		
		public DateTimeOffSetRangeValidatorAttribute(DateTime upperBound)
			: this(default(DateTime), RangeBoundaryType.Ignore, upperBound, RangeBoundaryType.Inclusive)
		{ }

		
		public DateTimeOffSetRangeValidatorAttribute(string lowerBound, string upperBound)
			: this(ConvertToISO8601Date(lowerBound), ConvertToISO8601Date(upperBound))
		{ }

		
		public DateTimeOffSetRangeValidatorAttribute(DateTime lowerBound, DateTime upperBound)
			: this(lowerBound, RangeBoundaryType.Inclusive, upperBound, RangeBoundaryType.Inclusive)
		{ }

		public DateTimeOffSetRangeValidatorAttribute(string lowerBound,
			RangeBoundaryType lowerBoundType,
			string upperBound,
			RangeBoundaryType upperBoundType)
			: this(ConvertToISO8601Date(lowerBound), lowerBoundType, ConvertToISO8601Date(upperBound), upperBoundType)
		{ }

		
        public DateTimeOffSetRangeValidatorAttribute(DateTime lowerBound,
			RangeBoundaryType lowerBoundType,
			DateTime upperBound,
			RangeBoundaryType upperBoundType)
		{
			this.lowerBound = lowerBound;
			this.lowerBoundType = lowerBoundType;
			this.upperBound = upperBound;
			this.upperBoundType = upperBoundType;
		}

		
		protected override Validator DoCreateValidator(Type targetType)
		{
			return new DateTimeOffSetRangeValidator(this.lowerBound,
				this.lowerBoundType,
				this.upperBound,
				this.upperBoundType,
				Negated);
		}

		private static DateTime ConvertToISO8601Date(string iso8601DateString)
		{
			if (string.IsNullOrEmpty(iso8601DateString))
			{
				return default(DateTime);
			}
			try
			{
				return DateTime.ParseExact(iso8601DateString, "s", CultureInfo.InvariantCulture);
			}
			catch (FormatException e)
			{
				throw new ArgumentException(String.Empty, "dateString", e);
			}
		}
    }
Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Sep 24, 2009 at 5:27 PM

 

Very good, i try code and it's ok.

I didn't think to implement a custom range validator

Thanks!!!