用于验证结束日期的自定义注释不会在开始日期之前到来

时间:2013-12-12 12:52:57

标签: c# asp.net-mvc-4 data-annotations

对于我的预订系统,我需要检查用户在表单中输入的结束日期是否在用户在表单中输入的开始日期之前。我正在使用ASP.NET MVC 4 C Sharp。

我可以使用自定义注释吗?到目前为止我有这个,但是模型类中的日期下面出现红线,说“属性参数必须是常量表达式....”

    private readonly DateTime _startDate;
    private readonly DateTime _endDate;

    public DateComparisonAttribute(DateTime startDate, DateTime endDate) : base ("{1} is greater than {0}. The end date must come before start date")
    {
        _startDate = startDate;
        _endDate = endDate;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            if (_endDate < _startDate)
            {
                var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                return new ValidationResult("End Date Must Come After Start Date");
            }
        }
        return ValidationResult.Success;
    }

型号:

    [DateComparison(StartDate, EndDate, ErrorMessage = "Dates")]
    [DisplayName("Start Date (MM/DD/YYYY)")]
    public DateTime StartDate { get; set; }
    [DisplayName("End Date (MM/DD/YYYY)")]
    public DateTime EndDate { get; set; }

2 个答案:

答案 0 :(得分:1)

这是我之前根据Brad wilsons blog

的信息编写的

C#Attribute

public sealed class IsDateAfterAttribute: ValidationAttribute, IClientValidatable
  {
    protected abstract string GetValidationType();
    protected abstract bool CompareValues(DateTime value, DateTime propertyTestedValue, out ValidationResult validationResult);

    protected readonly string testedPropertyName;
    protected readonly bool allowEqualDates;

    protected int _maxSearchableDaysAhead;

    public IsDateAfterAttribute(string testedPropertyName, bool allowEqualDates = false)
    {
      this.testedPropertyName = testedPropertyName;
      this.allowEqualDates = allowEqualDates;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
      var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName);
      if (propertyTestedInfo == null)
      {
        return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName));
      }

      var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);

      if (value == null || !(value is DateTime))
      {
        return ValidationResult.Success;
      }

      if (propertyTestedValue == null || !(propertyTestedValue is DateTime))
      {
        return ValidationResult.Success;
      }

      ValidationResult returnVal;
      if (CompareValues((DateTime)value, (DateTime)propertyTestedValue, out returnVal))
      {
        return returnVal;
      }
      else
      {
        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
      }



    }

    protected override bool CompareValues(DateTime value, DateTime propertyTestedValue, out ValidationResult validationResult)
{
  validationResult = null;
  // Compare values
  if (value <= propertyTestedValue)
  {
    if (this.allowEqualDates)
    {
      validationResult = ValidationResult.Success;
      return true;
    }
    if (value < propertyTestedValue)
    {
      validationResult = ValidationResult.Success;
      return true;
    }

  }


  return false;
}

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {

      this._maxSearchableDaysAhead = Setting.GetSettingValue(SettingNames.MaxSearchableDaysAhead, 548);

      var rule = new ModelClientValidationRule
      {
        ErrorMessage = string.Format(this.ErrorMessageString, _maxSearchableDaysAhead),
        ValidationType = "isdateafter"
      };
      rule.ValidationParameters["propertytested"] = this.testedPropertyName;
      rule.ValidationParameters["allowequaldates"] = this.allowEqualDates;
      yield return rule;
    }
  }

JS

$.validator.unobtrusive.adapters.add(
    'isdateafter', ['propertytested', 'allowequaldates'], function (options) {
        options.rules['isdateafter'] = options.params;
        options.messages['isdateafter'] = options.message;
    });
    $.validator.addMethod("isdateafter", function (value, element, params) {
        var parts = element.name.split(".");
        var prefix = "";
        if (parts.length > 1)
            prefix = parts[0] + ".";
        var startdatevalue = $('input[name="' + prefix + params.propertytested + '"]').val();
        if (!value || !startdatevalue)
            return true;
        if (params.allowequaldates && params.allowequaldates.toLowerCase() == "true") 
                {
                    return Date.parse(startdatevalue) <= Date.parse(value); 
                }
                else
                {
                    return Date.parse(startdatevalue) < Date.parse(value);
                }
    });

已添加到模型

[DisplayName("Departure Dates")]
 public DateTime? DepartureFrom { get; set; }

 [DisplayName("Departure Dates")]
 [IsDateAfter("DepartureFrom", true, ErrorMessage = "* Departure To Date must be after Departure From Date")]
 public DateTime? DepartureTo { get; set; }

答案 1 :(得分:-1)

属性必须是常量,因为它们在编译时会添加到程序集中。所以,不能用自定义注释得到你想要的东西。