Reputation: 1140
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
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;
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