6

phép nói rằng tôi có một StartDate và EndDate và tôi wnt để kiểm tra xem EndDate là không quá 3 tháng ngoài các Ngày bắt đầuHãy so sánh Ngày DataAnnotations Validation asp.net MVC

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

và tôi muốn để thực hiện điều này vào xác nhận của tôi

[DateCompare ("StartDate", "EndDate", ErrorMessage = "The Deal chỉ có thể được kéo dài 3 tháng!")]

tôi biết tôi nhận được một lỗi ở đây ... nhưng làm cách nào tôi có thể thực hiện xác nhận quy tắc nghiệp vụ này trong asp.net mvc

+0

có câu trả lời cho điều này không? oliver, cái gì phù hợp với bạn? –

Trả lời

4

Tôi chỉ tìm ra cách thực hiện điều này ở cấp lớp chứ không phải ở cấp thuộc tính. Nếu bạn tạo một ứng dụng MVC, mô hình Tài khoản sẽ hiển thị cách tiếp cận được minh họa bên dưới.

Class:

[PropertiesMustMatch("Password", 
      "ConfirmPassword", ErrorMessage = 
      "Password and confirmation password 
      do not match.")] 
       public class RegisterModel 
       { 

        [Required(ErrorMessage = "Required")] 
        [DataType(DataType.EmailAddress)] 
        [DisplayName("Your Email")] 
        public string Email { get; set; }    

        [Required(ErrorMessage = "Required")] 
        [ValidatePasswordLength] 
        [DataType(DataType.Password)] 
        [DisplayName("Password")] 
        public string Password { get; set; } 

        [Required(ErrorMessage = "Required")] 
        [DataType(DataType.Password)] 
        [DisplayName("Re-enter password")] 
        public string ConfirmPassword { get; set; }     
       } 

Validation Phương pháp:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
    public sealed class PropertiesMustMatchAttribute : ValidationAttribute 
    { 
     private const string _defaultErrorMessage = "'{0}' and '{1}' do not match."; 

     private readonly object _typeId = new object(); 

     public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty) 
      : base(_defaultErrorMessage) 
     { 
      OriginalProperty = originalProperty; 
      ConfirmProperty = confirmProperty; 
     } 

     public string ConfirmProperty 
     { 
      get; 
      private set; 
     } 

     public string OriginalProperty 
     { 
      get; 
      private set; 
     } 

     public override object TypeId 
     { 
      get 
      { 
       return _typeId; 
      } 
     } 

     public override string FormatErrorMessage(string name) 
     { 
      return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, 
       OriginalProperty, ConfirmProperty); 
     } 

     public override bool IsValid(object value) 
     { 
      PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); 
      object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value); 
      object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value); 
      return Object.Equals(originalValue, confirmValue); 
     } 
} 
+0

Bạn đã tạo lớp học đó chưa? Hay bạn tìm thấy nó ở đâu đó? Khi mật khẩu không khớp, mật khẩu không hiển thị lỗi. Chắc chắn là tôi đang thiếu gì đó. Uhh nevermind, nó đi kèm với MVC –

+0

Nó là một phần của ứng dụng cơ sở MVC. Nó thêm lỗi vào _form, không phải là một thực thể cụ thể. – scottrakes

2

Các thuộc tính

public class CompareValidatorAttribute : ValidationAttribute, IInstanceValidationAttribute 
{ 
    public CompareValidatorAttribute(string prefix, string propertyName) { 
     Check.CheckNullArgument("propertyName", propertyName); 

     this.propertyName = propertyName; 
     this.prefix = prefix; 
    } 

    string propertyName, prefix; 

    public string PropertyName 
    { 
     get { return propertyName; } 
    } 

    public string Prefix 
    { 
     get { return prefix; } 
    } 

    #region IInstanceValidationAttribute Members 

    public bool IsValid(object instance, object value) 
    { 
     var property = instance.GetType().GetProperty(propertyName); 

     var targetValue = property.GetValue(instance, null); 
     if ((targetValue == null && value == null) || (targetValue != null && targetValue.Equals(value))) 
      return true; 

     return false; 
    } 

    #endregion 

    public override bool IsValid(object value) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Giao diện

public interface IInstanceValidationAttribute 
{ 
    bool IsValid(object instance, object value); 
} 

Các Validator

public class CompareValidator : DataAnnotationsModelValidator<CompareValidatorAttribute> 
{ 
    public CompareValidator(ModelMetadata metadata, ControllerContext context, CompareValidatorAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
    } 

    public override IEnumerable<ModelValidationResult> Validate(object container) 
    { 
     if (!(Attribute as IInstanceValidationAttribute).IsValid(container, Metadata.Model)) 
      yield return (new ModelValidationResult 
      { 
       MemberName = Metadata.PropertyName, 
       Message = Attribute.ErrorMessage 
      }); 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     var rule = new ModelClientValidationRule() { ErrorMessage = Attribute.ErrorMessage, ValidationType = "equalTo" }; 
     rule.ValidationParameters.Add("equalTo", "#" + (!string.IsNullOrEmpty(Attribute.Prefix) ? Attribute.Prefix + "_" : string.Empty)+ Attribute.PropertyName); 

     return new[] { rule }; 
    } 
} 

đăng ký nó:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CompareValidatorAttribute), typeof(CompareValidator)); 
+0

+1 Rất hữu ích để có điều này! – Robert

2

Cảm ơn thông tin. Tôi đã gãi đầu khi tôi muốn ràng buộc thông điệp xác thực vào một tài sản. Nếu bạn chuyển sang dòng

[AttributeUsage(AttributeTargets.Class)] 

để ...

[AttributeUsage(AttributeTargets.Property)] 

bạn có thể di chuyển các so sánh trên một tài sản cụ thể. Cảm ơn bạn về thông tin! Trợ giúp nhiều vì khách hàng của tôi vẫn chạy trên 3,5 sp1. buồn mặt

4
  1. Ngày

Entity:

[MetadataType(typeof(MyEntity_Validation))] 
public partial class MyEntity 
{ 
} 
public class MyEntity_Validation 
{ 
    [Required(ErrorMessage="'Date from' is required")] 
    public DateTime DateFrom { get; set; } 

    [CompareDatesValidatorAttribute("DateFrom")] 
    public DateTime DateTo { get; set; } 
} 

Thuộc tính:

public sealed class CompareDatesValidatorAttribute : ValidationAttribute 
{ 
    private string _dateToCompare; 
    private const string _errorMessage = "'{0}' must be greater or equal'{1}'"; 

    public CompareDatesValidatorAttribute(string dateToCompare) 
     : base(_errorMessage) 
    { 
     _dateToCompare = dateToCompare; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(_errorMessage, name, _dateToCompare); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var dateToCompare = validationContext.ObjectType.GetProperty(_dateToCompare); 
     var dateToCompareValue = dateToCompare.GetValue(validationContext.ObjectInstance, null); 
     if (dateToCompareValue != null && value != null && (DateTime)value < (DateTime)dateToCompareValue) 
     { 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 
     return null; 
    } 
} 

2.Mật khẩu

Entity:

public string Password { get; set; } 

    [Compare("Password", ErrorMessage = "ConfirmPassword must match Password")] 
    public string ConfirmPassword { get; set; } 

Tôi hy vọng nó giúp

+0

Các ví dụ hay và ngắn. Không cần cho $ .validator của jQuery. – Misi

8

Đó là một câu trả lời cuối nhưng tôi muốn chia sẻ nó cho những người khác outhere. Đây là cách tôi đã thực hiện nó để mọi thứ được xác nhận sử dụng không phô trương xác nhận khách hàng:

  1. Tạo một lớp thuộc tính:

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

    Lưu ý: nếu bạn muốn xác chiều dài của thời gian, thêm một tham số cho constractor và thay đổi điều tra cho loại hợp nhất cụ thể này

  2. Thêm thuộc tính vào trường như folows:
    [DateCompareValidation(DateCompareValidationAttribute.CompareType.GreatherThenOrEqualTo, "This Date must be on or after another date", compareWith: "AnotherDate")]

  3. Ghi chú cách html được tạo của bạn bị thay đổi. Nó sẽ bao gồm thông báo xác thực của bạn, tên trường cho ngày so sánh, v.v. Các parm được tạo sẽ bắt đầu bằng "data-val-compare". Bạn đã xác định "so sánh" này khi bạn đặt ValidationType = "compare" trong phương thức GetClientValidationRules.

  4. Bây giờ bạn cần mã javascript phù hợp: để thêm bộ điều hợp xác thực và phương thức xác thực. Tôi đã sử dụng phương pháp anonimous ở đây, nhưng bạn không phải. Tôi khuyên bạn nên đặt mã này trong một tệp javascript riêng biệt để tệp này cùng với lớp thuộc tính của bạn trở thành giống như một điều khiển và có thể được sử dụng ở mọi nơi.

$ .validator.unobtrusive.adapters.add ( 'so sánh', [ 'comparetodate', 'comparetype'], chức năng (tùy chọn) { options.rules [ 'so sánh' ] = 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; 
}); 

này sẽ chăm sóc duy nhất của client-side validation không phô trương. Nếu bạn cần phía máy chủ, bạn sẽ phải có một số logic trong việc ghi đè phương thức isValid. Ngoài ra, bạn có thể sử dụng Reflection để tạo ra thông báo lỗi bằng cách sử dụng thuộc tính hiển thị, vv và làm cho đối số thông báo tùy chọn.