Ich habe eine Spalte in meinem SQL Server 2008 mit der Art von Decimal(18,2)
. Aber was ist die beste Überprüfung von Datenanmerkungen, die ich für diese Eigenschaft in meiner asp.net MVC-Webanwendung anwenden kann?
Es gibt keine expliziten Datenanmerkungen für Dezimalzahlen, daher müssen Sie zum Hinzufügen von Einschränkungen zwei separate Annotationen verwenden.
[RegularExpression(@"^\d+\.\d{0,2}$")]
Dieser reguläre Ausdruck stellt sicher, dass die Eigenschaft höchstens zwei Dezimalstellen hat.
[Range(0, 9999999999999999.99)]
Angenommen, Sie akzeptieren keine negativen Zahlen. Andernfalls ersetzen Sie 0
durch -9999999999999999.99
.
[RegularExpression(@"^\d+\.\d{0,2}$")]
[Range(0, 9999999999999999.99)]
public decimal Property { get; set; }
Ich denke, die Antwort von @ jumpingcode kann zu einer RegularExpressionAttribute
kombiniert werden.
[RegularExpression(@"^(0|-?\d{0,16}(\.\d{0,2})?)$")]
public decimal Property
{
get;
set;
}
Dies kann für jede precision
und scale
verwendet werden. Die 16 wird durch precision
- scale
und die 2 durch die scale
ersetzt. Der reguläre Ausdruck sollte mit den eingegebenen Zahlen wie ###
, 0.##
, .##
, 0
und ###.##
sowie negativen Werten übereinstimmen.
Dies scheint die richtige Antwort zu sein (die obigen Antworten schränken entweder gültige Zahlen ein, die in einen Datentyp von Decimal (18,2) eingefügt werden können, oder verursachen Kompilierungsfehler, wenn Sie sie auf Ihren Code anwenden - bitte bestätigen Sie das selbst):
Verwenden Sie die beiden folgenden Bedingungen zusammen:
Zwei Dezimalpunkte
[RegularExpression(@"^\d+.?\d{0,2}$", ErrorMessage = "Invalid Target Price; Maximum Two Decimal Points.")]
Max 18 Ziffern
[Range(0, 9999999999999999.99, ErrorMessage = "Invalid Target Price; Max 18 digits")]
Für einen anderen Ansatz, den manche für lesbarer halten, können Sie die OnModelCreating-Methode Ihres DbContext überschreiben, um die Genauigkeit festzulegen.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<YourEntity>()
.Property(x => x.TheProprty)
.HasPrecision(18, 2);
}
Vorteil: stark typisiert im Vergleich zu benutzerdefinierten regulären Ausdrücken
Nachteil: Kann nicht mit einem Scan in der Klasse gesehen werden
[Range(1,(double) decimal.MaxValue, ErrorMessage="value should be between{1} and {2}."]
Nach einem @Schmalls-Beispiel (und einem Kommentar in ein Attribut) habe ich ein Arbeitsbeispiel erstellt (verwendet eine C # 6-String-Interpolation):
public class PrecisionAndScaleAttribute : RegularExpressionAttribute
{
public PrecisionAndScaleAttribute(int precision, int scale) : base([email protected]"^(0|-?\d{{0,{precision - scale}}}(\.\d{{0,{scale}}})?)$")
{
}
}
Verwendungszweck:
[PrecisionAndScale(6, 2, ErrorMessage = "Total Cost must not exceed $9999.99")]
public decimal TotalCost { get; set; }
Wenn Sie die Annotation 'column' schreiben, funktioniert dies problemlos
[Required]
[Column(TypeName = "decimal(18, 6)")]
public decimal Foo { get; set; }
Ich benutze fast alles (b/c ist einfach und funktioniert)
[Range(typeof(decimal), "0", "1")]
public decimal Split { get; set; }
Wenn ich dann wieder in Double konvertieren muss, füge ich eine Konvertierung hinzu
(double)model.Split