BattlFrog
BattlFrog

Reputation: 3397

Get value of a property that was passed in as a string

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

Answers (3)

10gler
10gler

Reputation: 879

validationContext has ObjectInstance which is an instance of SomeModel class so you can use: (validationContext.ObjectInstance as SomeModel).Prop1/Prop2

Upvotes: 0

VJAI
VJAI

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;}
}

Ref: http://www.concurrentdevelopment.co.uk/blog/index.php/2011/01/custom-validationattribute-for-comparing-properties/

Upvotes: 9

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

Related Questions