自定义日期RangeAttribute将在年,月和日的负值上返回异常

时间:2017-12-19 05:26:02

标签: c# exception-handling range customvalidator validationattribute

我创建了一个自定义DateRange属性来检查日期的最大值和最小值。这是代码

 public class DateRangeAttribute : RangeAttribute
    {
        public DateRangeAttribute(int minimumYear, int minimumMonth, int minimumDay, int maximumYear, int maximumMonth, int maximumDay)
            : base(typeof(DateTime), GetMinimumDate(minimumYear, minimumMonth, minimumDay).ToShortDateString()
                , GetMaximumDate(maximumYear, maximumMonth, maximumDay).ToShortDateString())
        {
        }

        private static DateTime GetMinimumDate(int minimumYear, int minimumMonth, int minimumDay)
        {
            if (minimumDay < 0 || minimumMonth < 0 || minimumYear < 0)
            {
                throw new ArgumentException( "the values for minimum date can not be negative." ,paramName: nameof(minimumMonth));

            }
            minimumYear = minimumYear == 0 ? DateTime.MinValue.Year : minimumYear;
            minimumMonth = minimumMonth == 0 ? DateTime.MinValue.Month : minimumMonth;
            minimumDay = minimumDay == 0 ? DateTime.MinValue.Day : minimumDay;
            return new DateTime(minimumYear, minimumMonth, minimumDay);
        }

        private static DateTime GetMaximumDate(int maximumYear, int maximumMonth, int maximumDay)
        {
            maximumYear = maximumYear == 0 ? DateTime.MaxValue.Year : maximumYear;
            maximumMonth = maximumMonth == 0 ? DateTime.MaxValue.Month : maximumMonth;
            maximumDay = maximumDay == 0 ? new DateTime(maximumYear, maximumMonth, 31) == DateTime.MaxValue.Date ?
                                           DateTime.MaxValue.Day : new DateTime(maximumYear, maximumMonth, 1).AddMonths(1).AddDays(-1).Day : maximumDay;

            return new DateTime(maximumYear, maximumMonth, maximumDay);
        }
   }

代码几乎可以正常工作。但是如果我传递Year / Month / Day的负值,它会在构造函数中崩溃。我在考虑在构造函数中进行值检查,当参数为负时可以抛出异常。像这样的东西

 private static DateTime GetMinimumDate(int minimumYear, int minimumMonth, int minimumDay)
  {
 if (minimumDay < 0 || minimumMonth < 0 || minimumYear < 0)
            {
                throw new ArgumentException( "the values for minimum date can not be negative." ,paramName: nameof(minimumMonth));

            }
         // The rest of the code...
   }  

但它不起作用。

更新:这是我使用此属性的方式

  [DateRange(1900, -1, 0, 0, 0, 0)]
  public DateTime? OriginalDocumentDate { get; set; }

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

一个mroe的东西,[DateRange(1900, -1, 0, 0, 0, 0)]当你这样做时,你正在传递使用该值初始化你的RangeAttribute意味着你将使用这个值来比较你输入的值,这个值与你传递的日期时间值进行比较财产。

尝试了这样的例子

public class Employee
{
    [DateRange(1900, -1, 0, 0, 0, 0)]
    public DateTime? OriginalDocumentDate { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Employee e = new Employee() { OriginalDocumentDate= DateTime.Now };
        List<ValidationResult> validationResults = new List<ValidationResult>();
        var vc = new ValidationContext(e, null, null);
        var isValid = Validator.TryValidateObject
                (e, vc, validationResults, true);
    }
}

并发现在Validator.TryValidateObject时没有构造函数被调用,这意味着这个属性只关注方法...即。当验证发生时,它只调用验证属性的方法而不是它的构造函数

我认为你必须把这段代码

 if (minimumDay < 0 || minimumMonth < 0 || minimumYear < 0)
            {
                throw new ArgumentException( "the values for minimum date can not be negative." ,paramName: nameof(minimumMonth));

            }

在你的方法调用中,因为在设置值之前调用了属性构造函数,即在创建类之前创建了类...

尝试在构造函数中放置断点...

以下代码

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(int[] values) {
        this.Values = values;
    }
}

[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }

使用数组[3,4,5]的值调用自定义属性构造函数,并且在属性初始化中传递值为self