使用数据注释将十进制值验证为小数点后 2 位?

Posted

技术标签:

【中文标题】使用数据注释将十进制值验证为小数点后 2 位?【英文标题】:Validate decimal value to 2 decimal places with data annotations? 【发布时间】:2012-03-22 10:43:28 【问题描述】:

我的视图模型中有这个:

[Required(ErrorMessage = "Price is required")]
[Range(0.01, 999999999, ErrorMessage = "Price must be greater than 0.00")]
[DisplayName("Price ($)")]
public decimal Price  get; set; 

我想验证用户输入的小数位数不超过 2 位。所以我想拥有

有效值:12、12.3、12.34

无效值:12.、12.345

有没有办法通过数据注释来验证这一点?

【问题讨论】:

【参考方案1】:

您可以使用 RegularExpression 属性和符合您条件的正则表达式。这里有一大堆涉及数字的表达方式,我相信其中一个会符合要求。这是link。

这将帮助您入门,尽管它可能不像您想要的那样具有包容性(需要至少一位小数点前导):

[RegularExpression(@"\d+(\.\d1,2)?", ErrorMessage = "Invalid price")]

请注意,很难发出精确的错误消息,因为您不知道正则表达式的哪一部分匹配失败(例如,字符串“z.22”具有正确的小数位数,但不是一个有效的价格)。

【讨论】:

这不适用于带有除句点 (.) 以外的小数分隔符的语言,例如逗号 (14,6),因为正则表达式使用当前区域性将十进制转换为字符串。 ^\d*(\.|,|(\.\d1,2)|(,\d1,2))?$ 怎么样,它同时使用句点和逗号,也允许在点之前没有前导数字或在点之后没有数字。 由于某种原因,给定的正则表达式允许我插入多个小数点,例如:1.22.3.44 @jahav,查看 franck-duhaupas 解决您问题的答案!【参考方案2】:
[RegularExpression(@"^\d+.\d0,2$",ErrorMessage = "Price can't have more than 2 decimal places")]
public decimal Price  get; set; 

这将满足小数点后 0 到 2 位,或者根本没有。

【讨论】:

您可能想要转义 '.' (这意味着“任何字符”如果没有转义)给 ^\d+\.\d0,5$ 哎呀,抱歉的意思是 ^\d+\.?\d0,5$ 带有 '?'只允许 0 或 1 次重复。 这实际上不允许没有小数位的值,即10但是,它确实允许没有小数位的点:10.【参考方案3】:

您还可以创建自己的 Decimal 验证属性,继承自 RegularExpressionAttribute:

 public class DecimalAttribute : RegularExpressionAttribute
 
    public int DecimalPlaces  get; set; 
    public DecimalAttribute(int decimalPlaces)
        : base(string.Format(@"^\d*\.?\d0,0$", decimalPlaces))
    
        DecimalPlaces = decimalPlaces;
    

    public override string FormatErrorMessage(string name)
    
        return string.Format("This number can have maximum 0 decimal places", DecimalPlaces);
    
 

并注册它以在 Application_Start() 中启用客户端验证:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(DecimalAttribute), typeof(RegularExpressionAttributeAdapter));

【讨论】:

【参考方案4】:
[RegularExpression(@"^\d+(\.\d)?$", ErrorMessage = "It cannot have more than one decimal point value")]
[Range( 0.1,100)]
public double xyzget;set;         

它适用于我的小数点后一位

【讨论】:

【参考方案5】:

使其适用于带小数点分隔符而非句点 (.) 的语言:

using System;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

/// <summary>
/// Decimal precision validator data annotation.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
public sealed class DecimalPrecisionAttribute : ValidationAttribute

  private readonly uint _decimalPrecision;

  public DecimalPrecisionAttribute(uint decimalPrecision)
  
    _decimalPrecision = decimalPrecision;
  

  public override bool IsValid(object value)
  
    return value is null || (value is decimal d && HasPrecision(d, _decimalPrecision));
  

  private static bool HasPrecision(decimal value, uint precision)
  
    string valueStr = value.ToString(CultureInfo.InvariantCulture);
    int indexOfDot = valueStr.IndexOf('.');
    if (indexOfDot == -1)
    
      return true;
    

    return valueStr.Length - indexOfDot - 1 <= precision;
  

用法:

[Required(ErrorMessage = "Price is required")]
[DecimalPrecision(2)]
[DisplayName("Price ($)")]
public decimal Price  get; set; 

【讨论】:

【参考方案6】:

您可以使用正则表达式进行此验证,并将其与 RegularExpression 属性一起应用。

【讨论】:

【参考方案7】:

我遇到了与 OP 相同的情况,但提供的答案并未提供适用于以下所有情况的解决方案:

12, 12.3 and 12.34

为此,我们使用以下正则表达式:

[RegularExpression(@"^\d+(.\d1,2)?$")]

【讨论】:

【参考方案8】:

类似于 ma​​ttytommo。你需要逃避'。' - 否则任何字符都将被接受

[RegularExpression(@"^\d+(\.\d1,2)?$")]

【讨论】:

以上是关于使用数据注释将十进制值验证为小数点后 2 位?的主要内容,如果未能解决你的问题,请参考以下文章

MVC3 十进制在编辑时被截断为 2 位小数

C#中的decimal怎么保留两位小数

SQL如何将整数值四舍五入到小数点后2位

十进制的最佳数据注释(18,2)

js 保留小数点2位

使用 ToString() 格式化十进制值以将逗号作为千位分隔符,其中小数位数未知