似乎无法设置自定义验证属性ErrorMessage

时间:2014-04-10 18:50:59

标签: javascript asp.net-mvc validation custom-attributes

我为我的MVC项目创建了一个自定义验证属性,允许我根据动态范围进行验证:

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()使用反射来查找提供的字段的值。

这是实现属性的地方:

[Display(Name = @"Chosen Amount")]
    [DynamicRange(0, "CurrentBalance")]
    public decimal ChosenAmount { get; set; }

验证本身效果很好,但ErrorMessage不匹配。从理论上讲,它应该显示(例如)“选择的数量必须在0到2500之间”或者当前的余额。相反,我得到了这个:

The field ChosenAmount must be a number.

这不仅与我的自定义错误消息不匹配,而且它也与默认的Range错误消息不匹配(另外,请注意它是拉取字段的实际名称而不是DisplayName)。为了测试它,我尝试在IsValid方法中手动执行验证(基本上返回_min&lt; = value&lt; = _max ),以防Range属性以某种方式覆盖,没有骰子。< / p>

我现在唯一的理论是它与我们格式化字段的方式有关:我们使用javascript将值掩盖为货币,因此2500变为$ 2500.00,-5变为($ 5.00)。我还没有尝试过禁用此功能(这是我的下一步),但我希望有人可能会遇到此问题并提供更好的解决方案。

谢谢,

  • 杰西

1 个答案:

答案 0 :(得分:1)

此错误消息与您的自定义验证属性无关。显示的原因是decimal字段的number验证失败。只要您使用$符号屏蔽输入,就不能再将其视为有效数字,因此您会看到错误。

要解决此问题,请停止屏蔽此字段或删除number验证规则:

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

另外,您应该知道,如果以$xxx格式发布此字段,服务器验证也会失败,因为DefaultModelBinder无法将此字段转换为{{1 }类型。在这种情况下,您必须为decimal创建自己的模型绑定器。