Wie kann ich mit dem Annotation-Attribut für Bereichsdaten eine minimale, aber keine maximale Dezimalstelle angeben?

150

Ich möchte angeben, dass ein Dezimalfeld für einen Preis> = 0 sein muss, aber ich möchte nicht wirklich einen Maximalwert festlegen.

Folgendes habe ich bisher ... Ich bin mir nicht sicher, wie ich das richtig machen soll.

[Range(typeof(decimal), "0", "??"] public decimal Price { get; set; }
user169867
quelle
Sicherlich, wenn dies in eine Datenbank geht, müssten Sie die maximal zulässige Anzahl basierend auf dem ausgewählten Datenbanktyp angeben? Andernfalls erhalten Sie eine böse Ausnahme, wenn diese Anzahl überschritten wird
Coops

Antworten:

226

Wie wäre es mit so etwas:

[Range(0.0, Double.MaxValue, ErrorMessage = "The field {0} must be greater than {1}.")]

Das sollte das tun, wonach Sie suchen, und Sie können die Verwendung von Zeichenfolgen vermeiden.

Jacob
quelle
1
Ich habe es für Int32 (Int32.MaxValue) verwendet und es ist in Ordnung, danke!
Bronek
15
Es zeigt jedoch eine dumme Validierungsnachricht :(The field Fixed price discount must be between 0.01 and 1.79769313486232E+308.
Piotr Kula
16
@ppumkin Använd ErrorMessage, dh [Range (0.0, Double.MaxValue, ErrorMessage = "Ihr Fehler hier")]
flafffl
Danke Jacob. Gute Antwort!
Pimbrouwers
1
@ppumkin erben von der DataAnnotationsModelValidator-Klasse, um Fehlermeldungen anzupassen
Alexander
91

Wenn Sie sich Sorgen machen, dass die Saite gut aussieht, können Sie dies tun:

    [Range(0, Double.PositiveInfinity)]

Dies hat eine Standardfehlermeldung von:

Das Feld SuchAndSuch muss zwischen 0 und Infinity liegen.

Jordanien
quelle
11
Dies ist meiner Meinung nach die beste Antwort hier, keine Erweiterungen, keine scheinbar zufälligen Zeichenfolgen / Zahlen, kein benutzerdefinierter Code und eine einigermaßen vernünftige Fehlermeldung.
Vitani
42

Es scheint keine andere Wahl zu sein, als den Maximalwert manuell einzugeben. Ich hatte gehofft, dass es eine Art Überlastung gibt, bei der Sie keine angeben müssen.

[Range(typeof(decimal), "0", "79228162514264337593543950335")]
public decimal Price { get; set; }
user169867
quelle
14
Dieser Code sieht einfach schrecklich aus. Ich würde vorschlagen, dataannotationsextensions.org über nuget und als Antwort von @Nicolai Schlenzig zu verwenden. Verwendung [Min(0)]- Dies hat auch eine bessere Validierungsnachricht. Ich würde vorschlagen, Ihre Antwort zu aktualisieren
Piotr Kula
Ich habe es aktualisiert, um es mit der besten Antwort hier
gleichzusetzen
Die obigen Antworten (@Jordan und @Jacob) sind viel angemessener. Zumal wir über Price sprechen. Ich verstehe, dass Transaktionen oft mit Dezimalwerten durchgeführt werden müssen, aber es gibt keinen Preis von 1,234 Dollar oder zumindest meistens möchten Sie dies dem Benutzer nicht zeigen.
Anastasios Selmanis
@AnastasiosSelmanis, ich stimme Ihnen zu, erwarten Sie den Teil, wenn Sie sagen "aber es gibt keinen Preis 1,234 Dollar". Sie gehen von USD aus, und selbst dann, wenn Sie dies für Devisen verwenden (obwohl hier von OP nicht erwähnt), geht USD in mehr Dezimalstellen über. =)
RoLYroLLs
35

Sie können verwenden:

[Min(0)]

Dies legt einen erforderlichen Minimalwert von 0 (Null) und keinen Maximalwert fest.

Sie benötigen DataAnnotationsExtensions , um dies zu verwenden.

Nicolai Schlenzig
quelle
8
Nein, ich denke nicht, dass das richtig ist. Es ist nicht Teil des Standard-MVC3-Frameworks von Data Annotations Extensions dataannotationsextensions.org . Bitte geben Sie einen MSDN-Link an.
Bernie White
1
NEIN - definitiv NICHT Teil von MVC 3 :( Aber diese Bibliothek ist eine gute Erweiterung, um irgendetwas zu haben :)
Piotr Kula
1
Nicht Teil von MVC3, aber nicht wichtig. Wenn Sie eine Validierung auf der Clientseite wünschen, müssen Sie nur das Paket DataAnnotationsExtensions.MVC3 verwenden. Diese beiden Pakete sind auf nuget verfügbar. Ich denke, dass dies der beste Ansatz ist, da Sie keine dumme Fehlermeldung haben oder die Fehlermeldung nicht jedes Mal neu definieren müssen, wenn Sie eine positive Ganzzahl oder Dezimalzahl validieren möchten (was ziemlich häufig vorkommt).
Gentiane
21

Wenn Sie mit Preisen arbeiten, können Sie sicher davon ausgehen, dass nichts mehr als 1 Billion Dollar kostet.

Ich würde verwenden:

[Range(0.0, 1000000000000)]

Oder wenn Sie es wirklich brauchen, fügen Sie einfach den Wert von Decimal.MaxValue(ohne Komma) ein:79,228,162,514,264,337,593,543,950,335

Beides funktioniert gut, wenn Sie nicht aus Simbabwe kommen.

John Farrell
quelle
7
Warum nicht einfach [Range(0.0,Decimal.MaxValue)]?
Coops
4
Wird nicht kompiliert, Decimal.MaxValue ist keine Konstante.
John Farrell
Diese Konstante ist ein Ärgernis, das Verweisen auf eine Ressourcendatei für Fehlertext ist nicht einfacher
Coops
3
Jetzt gehen Sie davon aus, dass die Währung Dollar ist, nicht Yen oder etwas anderes.
Fred
1
@jfar Decimal.MaxValue ist eine Konstante. Es ist nur so, dass der Bereich keine Überlastung hat, um eine Dezimalstelle aufzunehmen.
Г И І І
11

Sie können die benutzerdefinierte Validierung verwenden:

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public int IntValue { get; set; }

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public decimal DecValue { get; set; }

Typ der Validierungsmethoden:

public class ValidationMethods
{
    public static ValidationResult ValidateGreaterOrEqualToZero(decimal value, ValidationContext context)
    {
        bool isValid = true;

        if (value < decimal.Zero)
        {
            isValid = false;
        }

        if (isValid)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(
                string.Format("The field {0} must be greater than or equal to 0.", context.MemberName),
                new List<string>() { context.MemberName });
        }
    }
}
Erikas Pliauksta
quelle
2

Ich wollte so etwas ausprobieren:

[Range(typeof(decimal), ((double)0).ToString(), ((double)decimal.MaxValue).ToString(), ErrorMessage = "Amount must be greater than or equal to zero.")]

Das Problem dabei ist jedoch, dass der Compiler einen konstanten Ausdruck wünscht, der nicht zulässig ist ((double)0).ToString(). Der Compiler wird nehmen

[Range(0d, (double)decimal.MaxValue, ErrorMessage = "Amount must be greater than zero.")]
David T. Macknet
quelle
Würde jemand, der dies abgelehnt hat, bitte erklären, warum Sie meine Lösung für schlecht oder nicht hilfreich halten? Denn nur ein Downvoting ohne Erklärung ist absolut nicht hilfreich.
David T. Macknet
Ihre Fehlermeldung sollte "größer oder gleich" lauten.
Г И І І
Guter Fang. Hinzugefügt.
David T. Macknet
1

mit Range mit

[Range(typeof(Decimal), "0", "9999", ErrorMessage = "{0} must be a decimal/number between {1} and {2}.")]

[Range(typeof(Decimal),"0.0", "1000000000000000000"]

Hoffe es wird helfen

Abi
quelle
1

[Bereich (0,01,100000000, ErrorMessage = "Preis muss größer als Null sein!")]

Sohail Akhter
quelle
0

Ich würde sagen, decimal.MaxValue.ToString()da dies die effektive Obergrenze für den Dezmialtyp ist, entspricht dies dem Fehlen einer Obergrenze.

Dr. Herbie
quelle
4
Das Problem ist, dass dies keine Konstante ist. Sie erhalten diesen Fehler: Ein Attributargument muss ein konstanter Ausdruck, Ausdruckstyp oder
Arrayerstellungsausdruck
Wie ich weiter unten betonte, aber anscheinend wurde es von niemandem geschätzt.
David T. Macknet