使用数据注释将十进制值验证为小数点后 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】:类似于 mattytommo。你需要逃避'。' - 否则任何字符都将被接受
[RegularExpression(@"^\d+(\.\d1,2)?$")]
【讨论】:
以上是关于使用数据注释将十进制值验证为小数点后 2 位?的主要内容,如果未能解决你的问题,请参考以下文章