Reputation: 3436
I am trying to validate a form submit BUT i want to validate a property ONLY if another property is set to true.
my two properties:
[DisplayName(Translations.Education.IsFeaturette)]
public bool IsFeaturette { get; set; }
[DisplayName(Translations.Education.AddFeaturetteFor)]
[CusomValidatorForFeaturettes(IsFeaturette)]
public string[] Featurettes { get; set; }
custom annotation:
public class CusomValidatorForFeaturettes: ValidationAttribute
{
private readonly bool _IsFeatturette;
public CusomValidatorForFeaturettes(bool isFeatturette): base("NOT OK")
{
_IsFeatturette = isFeatturette;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null && _IsFeatturette )
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
return ValidationResult.Success;
}
}
Basiclly if isfeature is true then Featurettes MUST have a value!
Error im getting:
An object reference is required for the non-static field, method, or property 'EducationViewModel.IsFeaturette'
I can not make this property static cuz that would give me problems since this property is set with enityframework and I don't wish to change any of this. How can I accomplish this without making the property static?
Upvotes: 0
Views: 4556
Reputation:
Attributes are added to the metadata of the assembly at compile-time, and therefore its parameters must be known at compile-time. The error is generated because the your passing the value of a property (bool IsFeaturette
) to the attribute which is not static (it could be true
or false
at run-time).
Instead, pass a string indicating the name of the property to compare, and in the method, use reflection to get the value of the property.
public bool IsFeaturette { get; set; }
[CusomValidatorForFeaturettes("IsFeaturette")]
public string[] Featurettes { get; set; }
and modify the validation attribute to
public class CusomValidatorForFeaturettes: ValidationAttribute
{
private readonly string _OtherProperty;
public CusomValidatorForFeaturettes(string otherProperty): base("NOT OK")
{
_OtherProperty = otherProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// Get the dependent property
var otherProperty = validationContext.ObjectInstance.GetType().GetProperty(_OtherProperty);
// Get the value of the dependent property
var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
......
You can then convert otherPropertyValue
to bool
and do your conditional check.
I also recommend you read The Complete Guide to Validation in ASP.NET-MVC-3 Part-2 to better understand how to implement a validation attribute, including how to implement IClientValidatable
so that you get both server and client side validation. I also recommend you rename the method to (say) RequiredIfTrueAttribute
to better reflect what it is doing.
Note also that foolproof have a good range of validation attributes for use in MVC.
And as a final note, your current implementation is specific to a dependency on one property (the value of IsFeaturette
), which is pointless for a validation attribute - you would have been better off just checking the values in the controller and adding a ModelStateError
. The code above means that you can pass in any property name (so long as that property was typeof bool
) which is what a validation attribute should allow.
Upvotes: 2