如何使用范围数据注释属性指定最小但没有最大小数?

211

我想指定一个用于价格的十进制字段必须 >= 0,但我不希望强制设置最大值。

这是我目前的内容...我不确定正确的方法是什么。

[Range(typeof(decimal), "0", "??"] public decimal Price { get; set; }

如果这个数据要存入数据库的话,你需要根据所选择的数据库类型指定允许的最大数量,否则如果超出了这个数量,你会得到一个非常不好的异常。 - Paul C
10个回答

319

试试这样:

[Range(0.0, Double.MaxValue, ErrorMessage = "The field {0} must be greater than {1}.")]

这应该可以做到你想要的,并且你可以避免使用字符串。


1
我已经使用它来处理Int32(Int32.MaxValue),一切正常,谢谢! - Bronek
24
不过,它确实显示了一条愚蠢的验证信息 :( “固定价格折扣字段必须在0.01和1.79769313486232E+308之间。” - Piotr Kula
19
使用 ErrorMessage,即 [Range(0.0, Double.MaxValue, ErrorMessage = "你的错误信息")]。 - flafffl
1
@ppumkin 继承 DataAnnotationsModelValidator 类以自定义错误消息。 - Alexander

127

如果您关心字符串的外观,请按照以下方式操作:

    [Range(0, Double.PositiveInfinity)]

这将有一个默认的错误信息:

字段SuchAndSuch必须在0和Infinity之间。


13
在我看来,这是最好的答案,没有任何扩展、看似随机的字符串/数字或自定义代码,并且提供了一个相当明智的错误信息。 - Vitani
哇,那很酷。使用PositiveInfinity而不是MaxValue还有其他优点吗? - Enrico
1
@Enrico 有意义的消息看起来像是一个很大的优势。但是是否存在不足之处呢?如果您输入一个对于数据库来说太大但小于无穷大的值,会发生什么呢?实际上,我怀疑我永远不会担心这个问题。 - Auspex
1
这很好,但从技术上讲,十进制数的最大值为“79,228,162,514,264,337,593,543,950,335”,而不是无限大。这对用户来说很容易理解,但在技术上是错误的。作为开发人员,我们有一个习惯,就是把事情简单化,但却是错误的。 - Marius

54

看起来只能手动设置最大值了。我希望有一种不需要指定最大值的重载方式。

[Range(typeof(decimal), "0", "79228162514264337593543950335")]
public decimal Price { get; set; }

19
这段代码看起来很糟糕。我建议使用Nuget上的http://dataannotationsextensions.org/, 如@Nicolai Schlenzig所回答。使用 [Min(0)] - 这也有更好的验证信息。我建议更新你的回答。 - Piotr Kula
我已经更新了它,使其与最佳答案保持一致,因为楼主不改变他的想法哈哈。 - Worthy7
以上 (@Jordan 和 @Jacob) 的答案更为恰当,特别是因为我们正在谈论价格。我知道许多交易必须以小数值进行,但并没有 1.234 美元这样的价格,或者至少大多数时候您不希望向用户展示这个。 - Anastasios Selmani
@AnastasiosSelmanis,我同意你的观点,除了你说“但是没有1.234美元的价格”的部分。你假设是美元,即使如此,在外汇交易中使用时(虽然OP没有提到),美元也会有更多的小数位。=) - RoLYroLLs

42

你可以使用以下代码:

[Min(0)]

这将强制要求最小值为0(零),没有最大值。

您需要使用DataAnnotationsExtensions来实现此操作。


12
不,我认为这不正确。它不是标准MVC3框架的一部分,而是来自Data Annotations Extensions http://dataannotationsextensions.org/。请提供一个MSDN链接。 - Bernie White
2
不好意思,它绝对不是 MVC 3 的一部分 :( 但那个库是一个很好的扩展,无论如何都值得拥有 :) - Piotr Kula
2
不属于MVC3,但这并不重要。如果您想在客户端进行验证,只需使用DataAnnotationsExtensions.MVC3包即可。这两个包都可以在NuGet上获得。 我认为这是最好的方法,因为您不需要愚蠢的错误消息,也不需要每次想要验证正整数或小数(这是相当常见的)时重新定义错误消息。 - gentiane

23

如果你正在处理价格,我相信你可以安全地假设没有任何东西的价值超过1万亿美元。

我会使用:

[Range(0.0, 1000000000000)]

或者,如果你真的需要,只需粘贴Decimal.MaxValue的值(不带逗号):79228162514264337593543950335

如果你不是来自津巴布韦的人,这两个都可以很好地工作。


7
为什么不只是使用 [Range(0.0, Decimal.MaxValue)] - Paul C
7
编译不通过,Decimal.MaxValue不是一个常量。 - John Farrell
那个常量真是个麻烦,要去资源文件中查找错误文本也不容易。 - Paul C
4
现在你做出了假设,即货币是美元,而不是日元或其他货币。 - Fred
3
@jfar:Decimal.MaxValue是一个常量。只是Range类没有重载来容纳一个decimal类型的值。 - Ε Г И І И О

13

您可以使用自定义验证:

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public int IntValue { get; set; }

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public decimal DecValue { get; set; }

验证方法类型:

public class ValidationMethods
{
    public static ValidationResult ValidateGreaterOrEqualToZero(decimal value, ValidationContext context)
    {
        bool isValid = true;

        if (value < decimal.Zero)
        {
            isValid = false;
        }

        if (isValid)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(
                string.Format("The field {0} must be greater than or equal to 0.", context.MemberName),
                new List<string>() { context.MemberName });
        }
    }
}

4
我打算尝试这样做:
[Range(typeof(decimal), ((double)0).ToString(), ((double)decimal.MaxValue).ToString(), ErrorMessage = "Amount must be greater than or equal to zero.")]

这样做的问题是编译器需要一个常量表达式,这不允许使用 ((double)0).ToString()。编译器可以接受其他表达式。
[Range(0d, (double)decimal.MaxValue, ErrorMessage = "Amount must be greater than zero.")]

你的错误信息应该说“大于或等于”。 - Ε Г И І И О
好的,已添加。 - David T. Macknet

2
使用 Range 进行区间操作
[Range(typeof(Decimal), "0", "9999", ErrorMessage = "{0} must be a decimal/number between {1} and {2}.")]

[Range(typeof(Decimal),"0.0", "1000000000000000000"]

希望这能有所帮助。


1
[Range(0.01,100000000,ErrorMessage = "价格必须大于零!")]

-2

我会使用 decimal.MaxValue.ToString(),因为这是 decimal 类型的有效上限,相当于没有上限。


5
问题在于它不是一个常量。你会看到这个错误:属性参数必须是常量表达式、typeof 表达式或者属性参数类型的数组创建表达式。 - user169867
正如我在下面指出的那样,但显然有人并不欣赏。 - David T. Macknet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接