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; }

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.


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.


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; }

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.


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.


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 });
        }
    }
}

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.")]

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


1

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


0

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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.