programing

내 속성 값을 내 모델 클래스의 다른 속성 값과 비교하는 사용자 지정 유효성 검사 속성

kingscode 2021. 1. 14. 22:56
반응형

내 속성 값을 내 모델 클래스의 다른 속성 값과 비교하는 사용자 지정 유효성 검사 속성


내 속성 값을 내 모델 클래스의 다른 속성 값과 비교하려는 사용자 지정 유효성 검사 속성을 만들고 싶습니다. 예를 들어 내 모델 클래스에 있습니다.

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

다음과 같이 사용하기 위해 사용자 지정 속성을 만들고 싶습니다.

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

어떻게 거기에 갈 수 있습니까?


다른 속성 값을 얻는 방법은 다음과 같습니다.

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

내 예는 아래를 참조하십시오.

모델 클래스 구현INotifyPropertyChanged

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

속성 클래스 에는 이벤트 헨들러도 포함됩니다.

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

용법

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

코드를 단순화하기 위해 유효성 검사를 생략하기로 결정했습니다.


이를 수행하는 가장 좋은 방법은 IValidatableObject를 사용하는 것입니다. http://msdn.microsoft.com/en-us/data/gg193959.aspx 참조

ReferenceURL : https://stackoverflow.com/questions/11959431/custom-validation-attribute-that-compares-the-value-of-my-property-with-another

반응형