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

时间:2012-03-04 20:33:38

标签: c# asp.net asp.net-mvc asp.net-mvc-3

我在我的视图模型中有这个:

[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

有没有办法用数据注释验证这个?

8 个答案:

答案 0 :(得分:25)

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

这会让你开始,虽然它可能没有你想要的包容性(需要至少一个数字领先小数点):

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

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

答案 1 :(得分:18)

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

这将满足0到2个小数位,或者根本不需要。

答案 2 :(得分:5)

您还可以创建自己的十进制验证属性,继承自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));

答案 3 :(得分:4)

[RegularExpression(@"^\d+(\.\d)?$", ErrorMessage = "It cannot have more than one decimal point value")]
[Range( 0.1,100)]
public double xyz{get;set;}         

它最适合我一个十进制值

答案 4 :(得分:3)

要使其适用于带小数点分隔符(而不是句点(。))的语言:

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

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

12, 12.3 and 12.34

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

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

答案 7 :(得分:0)

mattytommo 类似。你需要逃避&#39;。&#39; - 否则将接受任何角色

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