Reputation: 3397
I am trying to create a custom validation that says "if the otherValue is true, then this value must be greater than 0. I am able to get the value in, but the way I currently have the otherValue set up, I only have the name of the property, not the value. Probably because it passed in as a string. This attribute is going to be on 5 or 6 different properties and each time, it will be calling a different otherValue. Looking for help on how to get the actual value (it is a bool) of otherValue.
Here is my current code:
public class MustBeGreaterIfTrueAttribute : ValidationAttribute, IClientValidatable
{
// get the radio button value
public string OtherValue { get; set; }
public override bool IsValid(object value)
{
// Here is the actual custom rule
if (value.ToString() == "0")
{
if (OtherValue.ToString() == "true")
{
return false;
}
}
// If all is ok, return successful.
return true;
}
======================EDIT=========================
Here is where I am at now, and it works! Now I need a refernce on how to make it so I can put in a different errorMessage when adding the attribute in the model:
public class MustBeGreaterIfTrueAttribute : ValidationAttribute, IClientValidatable
{
// get the radio button value
public string OtherProperty { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var otherPropertyInfo = context.ObjectInstance.GetType();
var otherValue = otherPropertyInfo.GetProperty(OtherProperty).GetValue(context.ObjectInstance, null);
// Here is the actual custom rule
if (value.ToString() == "0")
{
if (otherValue.ToString().Equals("True", StringComparison.InvariantCultureIgnoreCase))
{
return new ValidationResult("Ensure all 'Yes' answers have additional data entered.");
}
}
// If all is ok, return successful.
return ValidationResult.Success;
}
// Add the client side unobtrusive 'data-val' attributes
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ValidationType = "requiredifyes";
rule.ErrorMessage = this.ErrorMessage;
rule.ValidationParameters.Add("othervalue", this.OtherProperty);
yield return rule;
}
}
So I should be able to do this:
[MustBeGreaterIfTrue(OtherProperty="EverHadRestrainingOrder", ErrorMessage="Enter more info on your RO.")]
public int? ROCounter { get; set; }
Upvotes: 1
Views: 5072
Reputation: 879
validationContext has ObjectInstance which is an instance of SomeModel class so you can use:
(validationContext.ObjectInstance as SomeModel).Prop1/Prop2
Upvotes: 0
Reputation: 32758
The ValidationAttribute
has a pair of IsValid
methods and for your scenario you have to use other guy.
public class MustBeGreaterIfTrueAttribute : ValidationAttribute
{
// name of the OtherProperty. You have to specify this when you apply this attribute
public string OtherPropertyName { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var otherProperty = validationContext.ObjectType.GetProperty(OtherPropertyName);
if (otherProperty == null)
return new ValidationResult(String.Format("Unknown property: {0}.", OtherPropertyName));
var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
if (value.ToString() == "0")
{
if (otherPropertyValue != null && otherPropertyValue.ToString() == "true")
{
return null;
}
}
return new ValidationResult("write something here");
}
}
Example Usage:
public class SomeModel
{
[MustBeGreaterIf(OtherPropertyName="Prop2")]
public string Prop1 {get;set;}
public string Prop2 {get;set;}
}
Upvotes: 9
Reputation: 31184
I'm having a little bit of trouble understanding what you want to do, but,
If you want to get the boolean representation of OtherValue, you could do
bool.Parse(this.OtherValue);
also, for string comparison, it sometimes helps to take case and whitespace out of the picture
if (this.OtherValue.ToString().ToLower().Trim() == "true")
Upvotes: 0