比较日期DataAnnotations验证asp.net mvc [英] Compare Dates DataAnnotations Validation asp.net mvc

查看:970
本文介绍了比较日期DataAnnotations验证asp.net mvc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个StartDate和一个EndDate,并且我wnt检查EndDate是否不超过开始日期3个月。

Lets say I have a StartDate and an EndDate and I wnt to check if the EndDate is not more then 3 months apart from the Start Date

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);
    }
}

/ p>

and I would like to implement this into my validation


[DateCompare(StartDate,EndDate,ErrorMessage =交易只能有3个月!)]

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

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

I know I get an error here... but how can I do this sort of business rule validation in asp.net mvc

推荐答案

这是一个晚了的答案,但我想分享给其他人。

It's a late answer but I wanted to share it for others outhere. Here's how I've done it so that everything is validated using unobtrusive client validation:


  1. 创建一个属性类:

  1. Create an attribute class:

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;
}
}

注:如果要验证时间长度,为该特定类型的比较添加另一个参数并更改枚举器

Note: if you want to validate length of time, add another parameter to the constractor and change enumerator for this specific type of comparsion

将属性添加到字段中: [DateCompareValidation(DateCompareValidationAttribute.CompareType.GreatherThenOrEqualTo,This Date must be on or after another date,compareWith:AnotherDate)]

Add the attributes to the field as folows:
[DateCompareValidation(DateCompareValidationAttribute.CompareType.GreatherThenOrEqualTo, "This Date must be on or after another date", compareWith: "AnotherDate")]

记下你生成的html是如何改变的。它应该包括您的验证消息,比较日期的字段名称等。生成的parms将以data-val-compare开头。

Take a note how your generated html is changed. It should include your validation message, field name for the compare-to date, etc. The generated parms would start with "data-val-compare". You defined this "compare" when you set ValidationType="compare" in GetClientValidationRules method.

现在您需要匹配的JavaScript代码:添加验证适配器和验证方法。我在这里使用anonimous方法,但你不必。我建议将此代码放在单独的javascript文件中,以便此文件与您的属性类变得像一个控件,可以在任何地方使用。

Now you need matching javascript code: to add an validation adapter and validation method. I used anonimous method here, but you don't have to. I recommend placing this code in a separate javascript file so that this file together with your attribute class become like a control and could be used anywhere.




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

$.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方法中有一些逻辑。此外,您可以使用Reflection使用显示属性等来生成错误消息,并使消息参数可选。

This takes care only of client-side unobtrusive validation. If you need server side, you'd have to have some logic in the override of isValid method. Also, you can use Reflection to generate error message using display attributes, etc and make the message argument optional.

这篇关于比较日期DataAnnotations验证asp.net mvc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆