48

我的 sql server 2008 中有一个列,类型为Decimal(18,2). 但是在实体框架上,我可以在我的 asp.net MVC Web 应用程序中应用到这个属性的最佳数据注释验证是什么?

4

10 回答 10

70

小数没有明确的数据注释,因此您需要使用两个单独的注释来添加约束。

两个小数点

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

此正则表达式将确保该属性最多有两位小数。

最多 18 位

[Range(0, 9999999999999999.99)]

假设您不接受任何负数。否则,替换0-9999999999999999.99

结果

[RegularExpression(@"^\d+(\.\d{1,2})?$")]
[Range(0, 9999999999999999.99)]
public decimal Property { get; set; }
于 2013-11-06T14:42:29.947 回答
26

我认为@jumpingcode 的答案可以合并为一个RegularExpressionAttribute

[RegularExpression(@"^(0|-?\d{0,16}(\.\d{0,2})?)$")]
public decimal Property
{
    get;
    set;
}

这可用于任何precisionscale。16 被替换为precision-scale并且 2 被替换为scale。正则表达式应匹配输入的数字,如###0.##.##0###.##以及负值。

于 2014-10-21T20:09:53.263 回答
10

对于某些人可能认为更具可读性的不同方法,您可以覆盖 DbContext 的 OnModelCreating 方法以设置精度,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

           modelBuilder.Entity<YourEntity>()
                    .Property(x => x.TheProprty)
                    .HasPrecision(18, 2);
    }

优点:强类型 vs 自定义正则表达式

缺点:仅扫描无法在课堂上看到它

于 2016-08-02T10:36:19.103 回答
8

如果您编写“列”注释,则可以正常工作

    [Required]
    [Column(TypeName = "decimal(18, 6)")]
    public decimal Foo { get; set; }
于 2019-04-30T13:37:57.533 回答
6

继@Schmalls 示例(并评论将其重新构建为属性)之后,我创建了一个工作示例(使用 C# 6 字符串插值):

public class PrecisionAndScaleAttribute : RegularExpressionAttribute
{
    public PrecisionAndScaleAttribute(int precision, int scale) : base($@"^(0|-?\d{{0,{precision - scale}}}(\.\d{{0,{scale}}})?)$")
    {

    }
}

用法:

[PrecisionAndScale(6, 2, ErrorMessage = "Total Cost must not exceed $9999.99")]
public decimal TotalCost { get; set; }
于 2018-06-22T14:42:44.860 回答
6

这似乎是正确的答案(上面的答案要么限制可以插入到 Decimal(18,2) 数据类型中的有效数字,要么在将它们应用于代码时导致编译错误——请自行确认):

一起使用以下两个约束:

两个小数点

[RegularExpression(@"^\d+.?\d{0,2}$", ErrorMessage = "Invalid Target Price; Maximum Two Decimal Points.")]

最多 18 位

  [Range(0, 9999999999999999.99, ErrorMessage = "Invalid Target Price; Max 18 digits")]
于 2015-12-01T03:02:02.647 回答
0

我使用的几乎是 excplusively(b/c 它很简单而且有效)

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

然后,如果我需要转换回双倍,我会添加一个转换

(double)model.Split
于 2018-04-29T16:16:44.460 回答
0
 [Range(1,(double) decimal.MaxValue, ErrorMessage="value should be between{1} and {2}."]
于 2016-05-25T04:15:39.547 回答
0

EF Core 6中

您可以简单地使用:

[Precision(18,2)]
public decimal Property{ get; set; }
于 2022-01-11T06:23:17.897 回答
0

.net core/5/6 解决方案,适用于 2021 年

using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;

[AttributeUsage(AttributeTargets.Property)]
public class ScalePrecisionValidationAttribute : ValidationAttribute
{
    private int _scale;
    private int _precision;

    public ScalePrecisionValidationAttribute(int scale, int precision)
    {
        _scale = scale;
        _precision = precision;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            if (!Regex.IsMatch(value.ToString(), $@"^(0|-?\d{{0,{scale-precision}}}(\.\d{{0,{precision}}})?)$"))
            {
                return new ValidationResult($"Allowed scale: {_scale}, precision: {_precision}");
            }
        }

        return ValidationResult.Success;
    }
}

用于

[ScalePrecisionValidationAttribute(8, 3)]
public decimal Weight { get; set; }

您可能需要根据用例添加/修改额外的防护。ps我使用Regex了其他答案之一的模式

于 2021-12-22T12:45:25.523 回答