Mangs
Mangs

Reputation: 1140

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

Upvotes: 1

Views: 2566

Answers (1)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64923

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.

Upvotes: 1

Related Questions