I have a web api with some nested models that are being bound like so:
public class Class1 {
//This data is needed in Class2 and Class3 validation
public bool ImportantInformation {get; set;}
public Class2 A {get; set;}
public Class3 B {get; set;}
}
public class Class2 {
[ConditionallyValidatedAttribute]
public string X {get; set;}
}
public class Class3 {
[ConditionallyValidatedAttribute]
public string Y {get; set;}
}
ConditionallyValidatedAttribute
looks like this:
public sealed class ConditionallyValidatedAttribute : ValidationAttribute {
protected override ValidationResult IsValid(object value, ValidationContext vc) {
bool importantInformation = //How do I get Class1.ImportantInformation?
if(importantImformation && value == null) {
return new ValidationResult($"{vc.MemberName} is invalid");
}
return ValidationResult.Success;
}
}
My question is is there some way to inject ImportantInformation
into ConditionallyValidatedAttribute
as needed?
As far as I know - there is no way to do that, as instance A
itself is not aware that it belongs to parent
.
But there is another way. Instead of applying ConditionallyValidatedAttribute
to property X
or Y
, you can apply it to entire A
or B
inside of your parent
. Doing that you can have access to the whole A
and ImportantInformation
inside of your IsValid
method. Something like that:
public class Class1
{
public bool ImportantInformation {get; set;}
[ConditionallyValidatedAttribute] //-->Validation Attribute here
public Class2 A {get; set;}
public Class3 B {get; set;}
}
public class Class2
{
public string X {get; set;}
}
public sealed class ConditionallyValidatedAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext vc)
{
var importantInformation = bool.Parse(vc.ObjectType.GetProperty("ImportantInformation")?.GetValue(vc.ObjectInstance)?.ToString() ?? "false");
if (importantInformation && (!(value is Class2) || string.IsNullOrEmpty(((Class2)value).X)))
{
return new ValidationResult($"{vc.MemberName} is invalid");
}
return ValidationResult.Success;
}
}