I've created a custom validation attribute for my MVC project, to allow me to validate based on a dynamic range:
public class DynamicRangeAttribute : ValidationAttribute
{
private readonly double _min;
private readonly double _max;
...
private DynamicRangeAttribute(double? min, double? max, string minProperty, string maxProperty)
{
_min = min ?? (double)GetValue<Decimal>(this, minProperty);
_max = max ?? (double)GetValue<Decimal>(this, maxProperty);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new RangeAttribute(_min, _max).IsValid(value) ? ValidationResult.Success
: new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
public override string FormatErrorMessage(string name)
{
return string.Format("{0} must be between {1} and {2}", name, _min, _max);
}
...
}
GetValue() uses reflection to find the value of the provided field.
Here is where the attribute is implemented:
[Display(Name = @"Chosen Amount")]
[DynamicRange(0, "CurrentBalance")]
public decimal ChosenAmount { get; set; }
The validation itself works great, but the ErrorMessage doesn't match up. In theory, it should display (for example) "Chosen Amount must be between 0 and 2500" or whatever the current balance is. Instead, I'm getting this:
Not only does this not match my custom error message, but it doesn't match the default Range error message, either (also, notice it's pulling the field's actual name rather than the DisplayName). Just to test it, I've tried performing validation manually in the IsValid method (essentially return _min <= value <= _max), in case the Range attribute was somehow overriding, no dice.
My only theory right now is that it has something to do with the way we're formatting the field: We use javascript to mask the value as currency, so 2500 becomes $2500.00, and -5 becomes ($5.00). I haven't tried disabling this yet (that's my next step), but I was hoping someone might have run into this before and could provide a better solution.
Thanks,