문제

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:

The field ChosenAmount must be a number.

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,

  • Jesse
도움이 되었습니까?

해결책

This error message has nothing to do with your custom validation attribute. It is shown because the number validation for your decimal field fails. As soon as you mask your input with a $ sign it cannot be considered as a valid number anymore, hence you see the error.

To fix the issue either stop masking this field or remove the number validation rule:

$("#input").rules("remove", "number");

Also you should be aware that if you post this field in the $xxx format, the server validation will fail too, as the DefaultModelBinder won't be able to convert this to a decimal type. In this case you will have to create you own model binder for decimal.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top