Search code examples
c#validationattribute

Get value inside custom validation attribute?


DI've created two custom validation attributes. After I've done the date validation I want to do the time validation, but to do that I need MyDate. How can I reach MyDate from inside the time validation?

My model:

[DateValidation()]
public DateTime MyDate { get; set;}

[TimeValidation()]
public TimeSpan MyTime { get; set;}

My TimeValidation:

public class TimeValidation: ValidationAttribute
{
    public override bool IsValid(object value)
    {
        TimeSpan time = (TimeSpan)value;
        DateTime MyDate //How can I get this?
        // Do stuff
        // return something good
    }       
}

Solution

  • If you check MSDN, it says for IsValid method:

    Determines whether the specified value of the object is valid.

    And, about the value parameter of IsValid it says:

    value Type: System.Object The value of the object to validate.

    Thus, your so-called date is the value and you just need to downcast it to DateTime:

    DateTime MyTime = (DateTime)value;
    

    Update

    Thats not really what I was looking for. I know how to do the validation with value. But in the vague example I gave you value is MyTime. But I also need MyDate inside the validation of MyTime. (I intentionally left out the validation of MyDate since it is working)

    You can't do that. At the end of the day, you're implementing an attribute and attributes are a type metadata detail. In other words: they can't know the object to which they're applied to.

    What you need is the IsValid(object, ValidationContext) overload, and the ValidationContext will give you the object to validate as the ObjectInstance property.

    Thus, you can access the other property using reflection:

    DateTime MyDate = (DateTime)validationContext.ObjectInstance.GetType()
                        .GetProperty("MyDate", BindingFlags.Public | BindingFlags.Instance)
                        .GetValue(validationContext.ObjectInstance);
    

    I would also add an argument to TimeValidation attribute called relatedPropertyName in order to don't hardcode the related property name.