2012-08-14 14 views
40

Özelliğimin değerini, model sınıfımdaki başka bir özelliğin değeriyle karşılaştırmak istediğim özel bir doğrulama özniteliği oluşturmak istiyorum. Benim modeli sınıfında var Örneğin :Özel doğrulama özelliği nasıl oluşturulur?

...  
public string SourceCity { get; set; } 
public string DestinationCity { get; set; } 

Ve özel bir oluşturmak istiyorum bu gibi kullanmak için özellik:

[Custom("SourceCity", ErrorMessage = "the source and destination should not be equal")] 
public string DestinationCity { get; set; } 
//this wil lcompare SourceCity with DestinationCity 

Oraya nasıl olabilir?

public class CustomAttribute : ValidationAttribute 
{ 
    private readonly string _other; 
    public CustomAttribute(string other) 
    { 
     _other = other; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var property = validationContext.ObjectType.GetProperty(_other); 
     if (property == null) 
     { 
      return new ValidationResult(
       string.Format("Unknown property: {0}", _other) 
      ); 
     } 
     var otherValue = property.GetValue(validationContext.ObjectInstance, null); 

     // at this stage you have "value" and "otherValue" pointing 
     // to the value of the property on which this attribute 
     // is applied and the value of the other property respectively 
     // => you could do some checks 
     if (!object.Equals(value, otherValue)) 
     { 
      // here we are verifying whether the 2 values are equal 
      // but you could do any custom validation you like 
      return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName)); 
     } 
     return null; 
    } 
} 
+1

http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx – Joe

+1

@Joe, bu ASP.NET MVC 2 içindir ve artık MVC 3 için geçerli değildir. Gönderi, OP'nin burada elde etmeye çalıştığı şey olan doğrulayıcı özellikteki değerleme değerinin nasıl alınacağını göstermez. –

cevap

67

diğer özellik değerini elde edebilir nasıl olay hendleyicisi içerir.

internal sealed class CustomAttribute : Attribute 
    { 
     public CustomAttribute(string propertyName) 
     { 
      PropertyName = propertyName; 
     } 

     public string PropertyName { get; set; } 

     public string ErrorMessage { get; set; } 

     public static void ThrowIfNotEquals(object obj, PropertyChangedEventArgs eventArgs) 
     { 
      Type type = obj.GetType(); 
      var changedProperty = type.GetProperty(eventArgs.PropertyName); 
      var attribute = (CustomAttribute)changedProperty 
               .GetCustomAttributes(typeof(CustomAttribute), false) 
               .FirstOrDefault(); 

      var valueToCompare = type.GetProperty(attribute.PropertyName).GetValue(obj, null); 
      if (!valueToCompare.Equals(changedProperty.GetValue(obj, null))) 
       throw new Exception("the source and destination should not be equal"); 
     } 
    } 

kodu basitleştirmek için

var test = new ModelClass(); 
    test.SourceCity = "1"; 
    // Everything is ok 
    test.DestinationCity = "1"; 
    // throws exception 
    test.DestinationCity ="2"; 

Kullanımı Bir doğrulama atlamak karar verdi.

+0

Harika, bu sadece bir cevap ** Ben ** arıyorum! Benim doğrulama durumumun dışında her zaman boş. Herhangi bir fikir? –

+2

@GrimmTheOpiner Bunun eski olduğunu biliyorum, ancak arayan herkes için 'public override bool' eklentisini eklemeyi deneyin RequiredValidationContext {get {return true; }} 'CustomAttribute ' – Ryan

+0

@Ryan Wow'da, bunu neden yapmak istedim? Hatırlayamasam bile, şu an iki işim daha var! :-) –

4

benim örneğin aşağıda bakınız:

Modeli sınıf uygular INotifyPropertyChanged da

public class ModelClass : INotifyPropertyChanged 
     { 
      private string destinationCity; 
      public string SourceCity { get; set; } 

      public ModelClass() 
      { 
       PropertyChanged += CustomAttribute.ThrowIfNotEquals; 
      } 

      [Custom("SourceCity", ErrorMessage = "the source and destination should not be equal")] 
      public string DestinationCity 
      { 
       get 
       { 
        return this.destinationCity; 
       } 

       set 
       { 
        if (value != this.destinationCity) 
        { 
         this.destinationCity = value; 
         NotifyPropertyChanged("DestinationCity"); 
        } 
       } 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 

      protected virtual void NotifyPropertyChanged(string info) 
      { 
       if (PropertyChanged != null) 
       { 
        PropertyChanged(this, new PropertyChangedEventArgs(info)); 
       } 
      } 
     } 

Özellik sınıfı İşte