model-view-controller - 比较日期 DataAnnotations Validation asp.net mvc

标签 model-view-controller validation compare date data-annotations

假设我有一个 StartDate 和一个 EndDate,我不想检查 EndDate 是否与开始日期相差不超过 3 个月

public class DateCompare : ValidationAttribute 
 {
    public String StartDate { get; set; }
    public String EndDate { get; set; }

    //Constructor to take in the property names that are supposed to be checked
    public DateCompare(String startDate, String endDate)
    {
        StartDate = startDate;
        EndDate = endDate;
    }

    public override bool IsValid(object value)
    {
        var str = value.ToString();
        if (string.IsNullOrEmpty(str))
            return true;

        DateTime theEndDate = DateTime.ParseExact(EndDate, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
        DateTime theStartDate = DateTime.ParseExact(StartDate, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture).AddMonths(3);
        return (DateTime.Compare(theStartDate, theEndDate) > 0);
    }
}

我想将其实现到我的验证中

[DateCompare("StartDate", "EndDate", ErrorMessage = "The Deal can only be 3 months long!")]



我知道我在这里遇到错误......但是我如何在 asp.net mvc 中进行这种业务规则验证

最佳答案

这是一个迟到的答案,但我想与其他人分享。这是我如何做到的,以便使用不显眼的客户端验证来验证所有内容:

  • 创建一个属性类:
    public class DateCompareValidationAttribute : ValidationAttribute, IClientValidatable
    {
    
      public enum CompareType
      {
          GreatherThen,
          GreatherThenOrEqualTo,
          EqualTo,
          LessThenOrEqualTo,
          LessThen
      }
    
    
    
    
      private CompareType _compareType;
      private DateTime _fromDate;
      private DateTime _toDate;
    
      private string _propertyNameToCompare;
    
      public DateCompareValidationAttribute(CompareType compareType, string message, string compareWith = "")
    {
        _compareType = compareType;
        _propertyNameToCompare = compareWith;
        ErrorMessage = message;
    }
    
    
    #region IClientValidatable Members
    /// <summary>
    /// Generates client validation rules
    /// </summary>
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ValidateAndGetCompareToProperty(metadata.ContainerType);
        var rule = new ModelClientValidationRule();
    
        rule.ErrorMessage = ErrorMessage;
        rule.ValidationParameters.Add("comparetodate", _propertyNameToCompare);
        rule.ValidationParameters.Add("comparetype", _compareType);
        rule.ValidationType = "compare";
    
        yield return rule;
    }
    
    #endregion
    
    
     protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
         // Have to override IsValid method. If you have any logic for server site validation, put it here. 
        return ValidationResult.Success;
    
    }
    
    /// <summary>
    /// verifies that the compare-to property exists and of the right types and returnes this property
    /// </summary>
    /// <param name="containerType">Type of the container object</param>
    /// <returns></returns>
    private PropertyInfo ValidateAndGetCompareToProperty(Type containerType)
    {
        var compareToProperty = containerType.GetProperty(_propertyNameToCompare);
        if (compareToProperty == null)
        {
            string msg = string.Format("Invalid design time usage of {0}. Property {1} is not found in the {2}", this.GetType().FullName, _propertyNameToCompare, containerType.FullName);
            throw new ArgumentException(msg);
        }
        if (compareToProperty.PropertyType != typeof(DateTime) && compareToProperty.PropertyType != typeof(DateTime?))
        {
            string msg = string.Format("Invalid design time usage of {0}. The type of property {1} of the {2} is not DateType", this.GetType().FullName, _propertyNameToCompare, containerType.FullName);
            throw new ArgumentException(msg);
        }
    
        return compareToProperty;
    }
    }
    

    注意:如果要验证时间长度,请向构造函数添加另一个参数并更改此特定类型比较的枚举器
  • 将属性添加到字段中,如下所示:[DateCompareValidation(DateCompareValidationAttribute.CompareType.GreatherThenOrEqualTo, "This Date must be on or after another date", compareWith: "AnotherDate")]
  • 记下您生成的 html 是如何更改的。它应该包括您的验证消息、比较日期的字段名称等。生成的参数将以“data-val-compare”开头。您在 GetClientValidationRules 方法中设置 ValidationType="compare"时定义了此“比较”。
  • 现在您需要匹配的 javascript 代码:添加验证适配器和验证方法。我在这里使用了匿名方法,但您不必这样做。我建议将此代码放在单独的 javascript 文件中,以便此文件与您的属性类一起成为一个控件,可以在任何地方使用。

  • $.validator.unobtrusive.adapters.add( 'compare', ['comparetodate', 'comparetype'], function (options) { options.rules['compare'] = options.params; options.messages['compare'] = options.message; } );


    $.validator.addMethod("compare", function (value, element, parameters) {
        // value is the actuall value entered 
        // element is the field itself, that contain the the value (in case the value is not enough)
    
        var errMsg = "";
        // validate parameters to make sure everyting the usage is right
        if (parameters.comparetodate == undefined) {
            errMsg = "Compare validation cannot be executed: comparetodate parameter not found";
            alert(errMsg);
            return false;
        }
        if (parameters.comparetype == undefined) {
            errMsg = "Compare validation cannot be executed: comparetype parameter not found";
            alert(errMsg);
            return false;
        }
    
    
        var compareToDateElement = $('#' + parameters.comparetodate).get();
        if (compareToDateElement.length == 0) {
            errMsg = "Compare validation cannot be executed: Element to compare " + parameters.comparetodate + " not found";
            alert(errMsg);
            return false;
        }
        if (compareToDateElement.length > 1) {
            errMsg = "Compare validation cannot be executed: more then one Element to compare with id " + parameters.comparetodate + " found";
            alert(errMsg);
            return false;
        }
        //debugger;
    
        if (value && !isNaN(Date.parse(value))) {
            //validate only the value contains a valid date. For invalid dates and blanks non-custom validation should be used    
            //get date to compare
            var compareToDateValue = $('#' + parameters.comparetodate).val();
            if (compareToDateValue && !isNaN(Date.parse(compareToDateValue))) {
                //if date to compare is not a valid date, don't validate this
                switch (parameters.comparetype) {
                    case 'GreatherThen':
                        return new Date(value) > new Date(compareToDateValue);
                    case 'GreatherThenOrEqualTo':
                        return new Date(value) >= new Date(compareToDateValue);
                    case 'EqualTo':
                        return new Date(value) == new Date(compareToDateValue);
                    case 'LessThenOrEqualTo':
                        return new Date(value) <= new Date(compareToDateValue);
                    case 'LessThen':
                        return new Date(value) < new Date(compareToDateValue);
                    default:
                        {
                            errMsg = "Compare validation cannot be executed: '" + parameters.comparetype + "' is invalid for comparetype parameter";
                            alert(errMsg);
                            return false;
                        }
                }
                return true;
            }
            else
                return true;
    
        }
        else
            return true;
    });
    

    这仅负责客户端不显眼的验证。如果您需要服务器端,则必须在 isValid 方法的覆盖中有一些逻辑。此外,您可以使用反射使用显示属性等生成错误消息,并使消息参数可选。

    关于model-view-controller - 比较日期 DataAnnotations Validation asp.net mvc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2848684/

    相关文章:

    php - 我如何在 laravel 的 Controller 中包含 Blade View ?

    asp.net-mvc - 在 MVC API 中接受字节数组参数作为 Base64

    model-view-controller - 如何将 mongoose 与 express.js 项目集成?

    validation - CakePHP - 使用相同规则验证多个字段

    javascript - 验证具有最小和最大范围的输入类型编号

    比较 nan(大于等于)

    c# - 为什么我提供数据时数据库却添加空值?

    javascript - 在 javascript、jquery 或 vue 中创建动态条件

    regex - 使用 sed linux 在具有特定字符串的行中输出一个数字

    Java:如何使用字符串比较用户和真实答案并确保其语法正确?