C
C#12mo ago
Shinigami

✅ ValidationContext in ASP.NET

What does ObjectInstance and ObjectType mean? afaik 1) ValidationContext is basically on which class the validation is performed. 2) ObjectInstance is where we have all the values for a model class 3) I'm not sure what object type is. What does this code do here?
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);

DateTime from_date = Convert.ToDateTime(otherproperty.GetValue(validationContext.ObjectInstance));
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);

DateTime from_date = Convert.ToDateTime(otherproperty.GetValue(validationContext.ObjectInstance));
I'm trying to fetch a different property value from in the same model class Model class
//Multiple Properties using Reflection
public string? FromDate { get; set; }

[DateRangeValidator("FromDate", ErrorMessage = "From Date should be less than To Date.")]
public string? ToDate { get; set; }
//Multiple Properties using Reflection
public string? FromDate { get; set; }

[DateRangeValidator("FromDate", ErrorMessage = "From Date should be less than To Date.")]
public string? ToDate { get; set; }
16 Replies
SeanJ
SeanJ12mo ago
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);
ObjectType would refer to the classtype so as you described 'Model Class'
Shinigami
ShinigamiOP12mo ago
so ObjectType is basically the T in Type T = Type.GetType("Model Class") ?
SeanJ
SeanJ12mo ago
Yeh essentially
Shinigami
ShinigamiOP12mo ago
what does validationcontext point to in this context?
SeanJ
SeanJ12mo ago
Think of it as like the context of what's being validated. Look at my recent code for example:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (PriorityServiceRegister)validationContext.ObjectInstance;
string fieldName = validationContext.MemberName;

if (model.PowerType == PowerType.Solar && fieldName == "SolarSerial")
...
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (PriorityServiceRegister)validationContext.ObjectInstance;
string fieldName = validationContext.MemberName;

if (model.PowerType == PowerType.Solar && fieldName == "SolarSerial")
...
}
It provides you access to the context of that validation that's being run (Sorry if this is a bad explanation). I can now view all the properties on my model and see their values etc. Hence why you use it to get the value of whatever property you're validating
Shinigami
ShinigamiOP12mo ago
ohkayy, let me tell you what i understood let's say i have a property called name and i need to validate it so the validationcontext basically has info regarding property called name right? like it's display name and membername etc.. now the validationcontext also has 2 more properties called ObjectType and ObjectInstance and we use objecttype to see all the properties/methods in the class and if needed we can get the reference of a single property as well now to see the actual value of the a property which we fetched using objectype, we need to use object instance? otherproperty.GetValue(validationContext.ObjectInstance) what does this code mean? why can't we just otherproperty.GetValue("propertyname") do this? alsoo, how are you directly accessing the value from ObjectInstance? is that because you casted it? var model = (PriorityServiceRegister)validationContext.ObjectInstance
SeanJ
SeanJ12mo ago
Sounds like you're beginning to understand it. Do you have the whole method? In theory Convert.ToDateTime(otherproperty.GetValue(validationContext.ObjectInstance)); is redundant as if you look at my above the Override for ValidationResult passes the value in directly.
Shinigami
ShinigamiOP12mo ago
exactly, i have the whole method, let me put it in here
SeanJ
SeanJ12mo ago
You can use validationContext if you want to gain a more granular access to the context of validation. For exmple your above could literally just be this:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var dateTo = Convert.ToDateTime(value);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var dateTo = Convert.ToDateTime(value);
}
Shinigami
ShinigamiOP12mo ago
casting your objectinstace to your model is easy and convenient like you did
SeanJ
SeanJ12mo ago
Above is pseudocode but you get the picture 🙂
Shinigami
ShinigamiOP12mo ago
yes yes, i just have 1 more doubt regarding this piece of code otherproperty.GetValue(validationContext.ObjectInstance) otherproperty basically has info about the property we want from the objectinstance so does that piece of code mean, get me the value of "otherproperty" from validationcontext.objectinstance?
public class DateRangeValidatorAttribute : ValidationAttribute
{
public string? PropertyName { get; set; }

public DateRangeValidatorAttribute(string OtherPropertyName)
{
PropertyName = OtherPropertyName;
}
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
if (value != null)
{
DateTime to_date = Convert.ToDateTime(value);

if (PropertyName != null)
{
var model = (User)validationContext.ObjectInstance;
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);

DateTime from_date = Convert.ToDateTime(otherproperty.GetValue(validationContext.ObjectInstance));

if(from_date < to_date)
{
return ValidationResult.Success;
}
}
{
return new ValidationResult("Please provide From Date");
}
}
else
{
return new ValidationResult("Please provide To Date");
}
}

}
}
public class DateRangeValidatorAttribute : ValidationAttribute
{
public string? PropertyName { get; set; }

public DateRangeValidatorAttribute(string OtherPropertyName)
{
PropertyName = OtherPropertyName;
}
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
if (value != null)
{
DateTime to_date = Convert.ToDateTime(value);

if (PropertyName != null)
{
var model = (User)validationContext.ObjectInstance;
PropertyInfo? otherproperty = validationContext.ObjectType.GetProperty(PropertyName);

DateTime from_date = Convert.ToDateTime(otherproperty.GetValue(validationContext.ObjectInstance));

if(from_date < to_date)
{
return ValidationResult.Success;
}
}
{
return new ValidationResult("Please provide From Date");
}
}
else
{
return new ValidationResult("Please provide To Date");
}
}

}
}
this is the whole code trying to fetch from date and the validationattribute is on to date property this
SeanJ
SeanJ12mo ago
var model = (User)validationContext.ObjectInstance; Exactly, the above now gives you access to your whole model and it's properties. Something to consider though: 1. Do you really want to just apply the validation to one out out of the two properties? Why? Well errors/feedback, you may want to have 1 error on the FromDate and another on the TooDate that feedbacks to the user
Shinigami
ShinigamiOP12mo ago
yes, sir. I'm currently learning this but i believe giving 2 different error from 2 properties sounds independent and i think that's how it should be
SeanJ
SeanJ12mo ago
Are the dates really nullable if you're requiring dates?
Shinigami
ShinigamiOP12mo ago
ideally they should not be nullable, like i was saying i'm just learning as of now following tutorials and stuff but thanks man! I feel like i really understood this stuff well enough to explain it back to someone I'm glad i had this convo
Want results from more Discord servers?
Add your server