如何使日期范围的自定义ValidationAttribute工作

时间:2019-08-26 18:32:02

标签: c# asp.net .net-core

我有一个.net核心应用程序,带有一个带有2个日期框的简单搜索页面,我想验证范围。我已经找到了一些有关如何在线执行此操作的示例,但是代码对我不起作用。 ValidationAttribute将针对我的模型中命名的另一个属性进行验证。问题是我在ValidationContext中寻找的属性始终为null。我已经调试了它,并且虽然我希望ValidationContext具有SearchModel的对象类型,但它具有DateTime的对象类型。

以下是相关代码。 SearchModel是Razor Page模型。错误发生在if(property == null)上。有人对我如何获得父母和访问DateOfBirthEnd属性有建议吗?

public class SearchModel
{
    [BindProperty]
    [DataType(DataType.Text)]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [BindProperty]
    [DataType(DataType.Text)]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [BindProperty]
    [Display(Name = "Date Of Birth Start")]
    [InputType(HtmlInputType.Text)]
    [Comparison("DateOfBirthEnd", ComparisonType.LessThan, ErrorMessage = "End date must be greater than start date")]
    public DateTime? DateOfBirthStart { get; set; }

    [BindProperty]
    [Display(Name = "Date Of Birth End")]
    [InputType(HtmlInputType.Text)]
    public DateTime? DateOfBirthEnd { get; set; }
}



[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
  public class ComparisonAttribute : ValidationAttribute
  {
    private readonly string _comparisonProperty;
    private readonly ComparisonType _comparisonType;

    public ComparisonAttribute(string comparisonProperty, ComparisonType comparisonType)
    {
      _comparisonProperty = comparisonProperty;
      _comparisonType = comparisonType;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
      ErrorMessage = ErrorMessageString;

      if (value.GetType() == typeof(IComparable))
      {
        throw new ArgumentException("value has not implemented IComparable interface");
      }

      var currentValue = (IComparable)value;

      var property =  validationContext.ObjectType.GetProperty(_comparisonProperty);

      if (property == null)
      {
        throw new ArgumentException("Comparison property with this name not found");
      }

      var comparisonValue = property.GetValue(validationContext.ObjectInstance);

      if (comparisonValue.GetType() == typeof(IComparable))
      {
        throw new ArgumentException("Comparison property has not implemented IComparable interface");
      }

      if (!ReferenceEquals(value.GetType(), comparisonValue.GetType()))
      {
        throw new ArgumentException("The properties types must be the same");
      }

      bool compareToResult;

      switch (_comparisonType)
      {
        case ComparisonType.LessThan:
          compareToResult = currentValue.CompareTo((IComparable)comparisonValue) >= 0;

          break;

        case ComparisonType.LessThanOrEqualTo:
          compareToResult = currentValue.CompareTo((IComparable)comparisonValue) > 0;

          break;

        case ComparisonType.EqualTo:
          compareToResult = currentValue.CompareTo((IComparable)comparisonValue) != 0;

          break;

        case ComparisonType.GreaterThan:
          compareToResult = currentValue.CompareTo((IComparable)comparisonValue) <= 0;

          break;

        case ComparisonType.GreaterThanOrEqualTo:
          compareToResult = currentValue.CompareTo((IComparable)comparisonValue) < 0;

          break;

        default:
          throw new ArgumentOutOfRangeException();
      }

      return compareToResult ? new ValidationResult(ErrorMessage) : ValidationResult.Success;
    }
  }

1 个答案:

答案 0 :(得分:0)

您的ValidationContext具有类型DateTime的属性,因为您将Attribute绑定到该属性。您可以尝试为Class用法创建另一个属性,因为这样可以为您提供整个SearchModel,并从此处验证两个DateTime字段。