J'ai une colonne à l'intérieur de mon serveur SQL 2008 avec le type de Decimal(18,2)
. Mais dans le cadre d'une entité, quelle est la meilleure validation d'annotation de données que je puisse appliquer à cette propriété dans mon application Web asp.net MVC?
Il n'y a pas d'annotation de données explicite pour une décimale, vous devez donc en utiliser deux distinctes pour ajouter des contraintes.
[RegularExpression(@"^\d+\.\d{0,2}$")]
Cette expression régulière garantira que la propriété a au plus deux décimales.
[Range(0, 9999999999999999.99)]
En supposant que vous n'acceptez aucun nombre négatif. Sinon, remplacez 0
par -9999999999999999.99
.
[RegularExpression(@"^\d+\.\d{0,2}$")]
[Range(0, 9999999999999999.99)]
public decimal Property { get; set; }
Je pense que la réponse de @ jumpingcode peut être combinée en une RegularExpressionAttribute
.
[RegularExpression(@"^(0|-?\d{0,16}(\.\d{0,2})?)$")]
public decimal Property
{
get;
set;
}
Ceci peut être utilisé pour toutes les variables precision
et scale
. Le 16 est remplacé par precision
- scale
et le 2 est remplacé par le scale
. L'expression régulière doit correspondre aux nombres entrés tels que ###
, 0.##
, .##
, 0
et ###.##
ainsi que des valeurs négatives.
Cela semble être la bonne réponse (les réponses ci-dessus restreignent les nombres valides pouvant être insérés dans un type de données Decimal (18,2) ou provoquent des erreurs de compilation en les appliquant à votre code - veuillez confirmer vous-même):
Utilisez les deux contraintes suivantes ensemble:
Deux décimales
[RegularExpression(@"^\d+.?\d{0,2}$", ErrorMessage = "Invalid Target Price; Maximum Two Decimal Points.")]
Max 18 chiffres
[Range(0, 9999999999999999.99, ErrorMessage = "Invalid Target Price; Max 18 digits")]
Pour une approche différente que certains pourraient considérer plus lisible, vous pouvez remplacer la méthode OnModelCreating de votre DbContext pour définir la précision, comme suit:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<YourEntity>()
.Property(x => x.TheProprty)
.HasPrecision(18, 2);
}
Avantage: expression régulière fortement typée vs personnalisée
Inconvénient: impossible de le voir dans la classe avec juste un scan
[Range(1,(double) decimal.MaxValue, ErrorMessage="value should be between{1} and {2}."]
Suite à l’exemple de @Schmalls (et à son commentaire en tant qu’attribut), j’ai créé un exemple de travail (utilise l’interpolation de chaîne en C # 6):
public class PrecisionAndScaleAttribute : RegularExpressionAttribute
{
public PrecisionAndScaleAttribute(int precision, int scale) : base($@"^(0|-?\d{{0,{precision - scale}}}(\.\d{{0,{scale}}})?)$")
{
}
}
Usage:
[PrecisionAndScale(6, 2, ErrorMessage = "Total Cost must not exceed $9999.99")]
public decimal TotalCost { get; set; }
J'utilise presque de manière excessive (c'est simple et ça marche)
[Range(typeof(decimal), "0", "1")]
public decimal Split { get; set; }
Ensuite, si je dois reconvertir en double, j'ajoute une conversion.
(double)model.Split