¿Cómo especificar un decimal mínimo pero no máximo utilizando el atributo de anotación de datos de rango?

150

Me gustaría especificar que un campo decimal para un precio debe ser> = 0, pero realmente no quiero imponer un valor máximo.

Esto es lo que tengo hasta ahora ... No estoy seguro de cuál es la forma correcta de hacer esto.

[Range(typeof(decimal), "0", "??"] public decimal Price { get; set; }
usuario169867
fuente
Seguramente, si esto va a entrar en una base de datos, ¿debería especificar el número máximo permitido en función del tipo de base de datos seleccionado? De lo contrario, obtendrá una desagradable excepción si se excede este número
Coops

Respuestas:

226

Qué tal algo como esto:

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

Eso debería hacer lo que está buscando y puede evitar el uso de cadenas.

Jacob
fuente
1
Lo he usado para Int32 (Int32.MaxValue) y está bien, ¡gracias!
Bronek
15
Sin embargo, muestra un estúpido mensaje de validación :( The field Fixed price discount must be between 0.01 and 1.79769313486232E+308.
Piotr Kula
16
@ppumkin Använd ErrorMessage, es decir, [Range (0.0, Double.MaxValue, ErrorMessage = "your error here")]
flafffl
Gracias Jacob ¡Gran respuesta!
pimbrouwers
1
@ppumkin hereda de la clase DataAnnotationsModelValidator para personalizar los mensajes de error
Alexander
91

Si le preocupa que la cadena se vea bien, puede hacer esto:

    [Range(0, Double.PositiveInfinity)]

Esto tendrá un mensaje de error predeterminado de:

El campo SuchAndSuch debe estar entre 0 e Infinity.

Jordán
fuente
11
Esta es la mejor respuesta aquí en mi humilde opinión, sin extensiones, sin cadenas / números aparentemente aleatorios, sin código personalizado y un mensaje de error razonablemente razonable.
Vitani
42

Parece que no hay más remedio que poner el valor máximo manualmente. Esperaba que hubiera algún tipo de sobrecarga en la que no necesitaras especificar una.

[Range(typeof(decimal), "0", "79228162514264337593543950335")]
public decimal Price { get; set; }
usuario169867
fuente
14
Este código se ve horrible. Sugeriría usar dataannotationsextensions.org a través de nuget y como respondió @Nicolai Schlenzig. Uso [Min(0)]: esto también tiene un mejor mensaje de validación. Sugeriría actualizar su respuesta
Piotr Kula
Lo actualicé para que sea la mejor respuesta aquí, ya que el OP no está cambiando de opinión jajaja
Worthy7
Las respuestas anteriores (@Jordan y @Jacob) son mucho más apropiadas. Especialmente porque estamos hablando de Price. Entiendo que muchas veces las transacciones deben hacerse con valores decimales, pero no hay ningún precio de 1.234 dólares o al menos la mayoría de las veces no desea mostrarle esto al usuario.
Anastasios Selmanis
@AnastasiosSelmanis, estoy de acuerdo con usted, espere la parte cuando diga "pero no hay ningún precio de 1.234 dólares". Está asumiendo USD, e incluso entonces, cuando usa esto para divisas (aunque OP no lo menciona aquí), USD entra en más decimales. =)
RoLYroLLs
35

Puedes usar:

[Min(0)]

Esto impondrá un valor mínimo requerido de 0 (cero) y ningún valor máximo.

Necesita DataAnnotationsExtensions para usar esto.

Nicolai Schlenzig
fuente
8
No, no creo que esto sea correcto. No es parte del marco MVC3 estándar, es de Data Annotations Extensions dataannotationsextensions.org . Proporcione un enlace de MSDN.
Bernie White
1
NO, definitivamente NO es parte de MVC 3 :( Pero esa biblioteca es una buena extensión para tener alguna forma :)
Piotr Kula
1
No forma parte de MVC3 pero no es importante. Si desea la validación en el lado del cliente, solo necesita usar el paquete DataAnnotationsExtensions.MVC3. Estos dos paquetes están disponibles en nuget. Creo que es el mejor enfoque, ya que no tiene un mensaje de error estúpido o no necesita redefinir el mensaje de error cada vez que desea validar un entero positivo o decimal (que es bastante común).
gentiane
21

Si trabaja con precios, estoy seguro de que puede asumir con seguridad que nada costará más de 1 billón de dólares.

Yo usaría:

[Range(0.0, 1000000000000)]

O si realmente lo necesita, simplemente pegue el valor de Decimal.MaxValue(sin las comas):79,228,162,514,264,337,593,543,950,335

Cualquiera de estos funcionará bien si no eres de Zimbabwe.

John Farrell
fuente
77
¿Por qué no solo [Range(0.0,Decimal.MaxValue)]?
Coops
44
No se compilará, Decimal.MaxValue no es una constante.
John Farrell
Esa constante es una molestia, en referencia a un archivo de recursos para el texto de error no es más fácil
Cooperativas
3
Ahora está asumiendo que la moneda es el dólar, no el yen o alguna otra cosa.
Fred
1
@jfar Decimal.MaxValue ES una constante. Es solo que el Rango no tiene sobrecarga para acomodar un decimal.
Ε Г И І И О
11

Puede usar validación personalizada:

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

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

Tipo de métodos de validación:

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
fuente
2

Iba a intentar algo como esto:

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

Sin embargo, el problema al hacer esto es que el compilador quiere una expresión constante, lo que no permite ((double)0).ToString(). El compilador se tome

[Range(0d, (double)decimal.MaxValue, ErrorMessage = "Amount must be greater than zero.")]
David T. Macknet
fuente
¿Quien haya rechazado esto, explique por qué cree que mi solución es pobre o no es útil? Porque simplemente votar sin ninguna explicación es totalmente inútil.
David T. Macknet
Su mensaje de error debe decir "mayor o igual que".
Ε Г И І И О
Buena atrapada. Adicional.
David T. Macknet
1

utilizando Range con

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

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

Espero que ayude

Abi
fuente
1

[Rango (0.01,100000000, ErrorMessage = "¡El precio debe ser mayor que cero!")]

Sohail Akhter
fuente
0

Me puse decimal.MaxValue.ToString()ya que este es el límite máximo efectivo para el tipo decmial es equivalente a no tener un límite superior.

Dr. herbie
fuente
44
El problema es que no es una constante. Obtendrá este error: un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo
user169867
Como señalé a continuación, pero aparentemente no fue apreciado por alguien.
David T. Macknet