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

本文关键字:验证 小数点 2位 十进制 数据 注释 | 更新日期: 2023-09-27 18:26:55

我的视图模型中有这个:

[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

有没有一种方法可以通过数据注释来验证这一点?

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

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

这将让你开始,尽管它可能没有你想要的那么包容(需要至少一位小数点前的数字):

[RegularExpression(@"'d+('.'d{1,2})?", ErrorMessage = "Invalid price")]

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

[RegularExpression(@"^'d+.'d{0,2}$",ErrorMessage = "Price can't have more than 2 decimal places")]
public decimal Price { get; set; }

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

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

 public class DecimalAttribute : RegularExpressionAttribute
 {
    public int DecimalPlaces { get; set; }
    public DecimalAttribute(int decimalPlaces)
        : base(string.Format(@"^'d*'.?'d{{0,{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));
[RegularExpression(@"^'d+('.'d)?$", ErrorMessage = "It cannot have more than one decimal point value")]
[Range( 0.1,100)]
public double xyz{get;set;}         

它适用于我,最多一个十进制值

我有与OP相同的场景,但提供的答案并不能提供适用于以下所有情况的解决方案:

12, 12.3 and 12.34

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

[RegularExpression(@"^'d+(.'d{1,2})?$")]

要使其适用于除句点(.)之外使用十进制分隔符的语言:

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; }

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

类似于mattytomo。你需要逃离"。"-否则将接受任何字符

[RegularExpression(@"^'d+('.'d{1,2})?$")]