Best Data annotation for a Decimal(18,2)

Solution 1:

There is no explicit data annotation for a decimal so you need to use two separate ones to add constraints.

Two Decimal Points

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

This regular expression will make sure that the property has at most two decimal places.

Max 18 digits

[Range(0, 9999999999999999.99)]

Assuming you aren't accepting any negative numbers. Otherwise, replace 0 with -9999999999999999.99.

Result

[RegularExpression(@"^\d+(\.\d{1,2})?$")]
[Range(0, 9999999999999999.99)]
public decimal Property { get; set; }

Solution 2:

I think @jumpingcode's answer can be combined into one RegularExpressionAttribute.

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

This can be used for any precision and scale. The 16 is replaced by precision - scale and the 2 is replaced by the scale. The regular expression should match numbers entered like ###, 0.##, .##, 0, and ###.## as well as negative values.

Solution 3:

For a different approach which some may consider more readable, you can override the OnModelCreating method of your DbContext to set precision, like so:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

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

Advantage: strongly typed vs custom regular expression

Disadvantage: can't see it on the class with just a scan