Como especificar um decimal mínimo, mas não decimal máximo, usando o atributo de anotação de dados do intervalo?


150

Gostaria de especificar que um campo decimal para um preço deve ser> = 0, mas não quero impor um valor máximo.

Aqui está o que tenho até agora ... Não sei qual é a maneira correta de fazer isso.

[Range(typeof(decimal), "0", "??"] public decimal Price { get; set; }

Certamente, se isso estiver entrando em um banco de dados, você precisará especificar o número máximo permitido com base no tipo de banco de dados selecionado? Caso contrário, você receberá uma exceção desagradável se este número for excedido
Coops

Respostas:


226

Que tal algo como isso:

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

Isso deve fazer o que você está procurando e pode evitar o uso de strings.


1
Eu usei para Int32 (Int32.MaxValue) e está tudo bem, obrigado!
Bronek

15
Ele mostra uma mensagem estúpida validação embora :(The field Fixed price discount must be between 0.01 and 1.79769313486232E+308.
Piotr Kula

16
@ppumkin Resposta ErrorMessage, ou seja, [Range (0.0, Double.MaxValue, ErrorMessage = "seu erro aqui")]
flafffl

Obrigado Jacob. Ótima resposta!
Pimbrouwers

1
@ppumkin herdar de uma classe DataAnnotationsModelValidator personalizar mensagens de erro
Alexander

91

Se você está preocupado com a aparência da string, você pode fazer o seguinte:

    [Range(0, Double.PositiveInfinity)]

Isso terá uma mensagem de erro padrão de:

O campo SuchAndSuch deve estar entre 0 e Infinito.


11
Esta é a melhor resposta aqui IMHO, sem extensões, sem seqüências aparentemente aleatórias / número, sem código personalizado e uma mensagem de erro razoavelmente sensata.
Vitani 14/03

42

Parece que não há escolha a não ser colocar o valor máximo manualmente. Eu esperava que houvesse algum tipo de sobrecarga em que você não precisasse especificar um.

[Range(typeof(decimal), "0", "79228162514264337593543950335")]
public decimal Price { get; set; }

14
Este código parece horrível. Eu sugeriria o uso de dataannotationsextensions.org via nuget e como @Nicolai Schlenzig respondeu. Use [Min(0)]- também possui uma mensagem de validação melhor. Sugiro atualizar sua resposta
Piotr Kula

I atualizado para torná-lo o mesmo que a melhor resposta aqui, já que o OP não está mudando sua mente lol
Worthy7

As respostas acima (@Jordan e @Jacob) são muito mais apropriadas. Especialmente porque estamos falando de preço. Entendo que muitas vezes as transações precisam ser feitas com valores decimais, mas não há preço de 1.234 dólares ou, pelo menos, na maioria das vezes, você não deseja mostrar isso ao usuário.
Anastasios Selmanis

@AnastasiosSelmanis, concordo com você, espere a parte quando você disser "mas não há nenhum preço 1,223 dólares". Você está assumindo o dólar e, mesmo assim, quando o usa para câmbio (embora não seja mencionado aqui pelo OP), o dólar entra em mais casas decimais. =)
RoLYroLLs

35

Você pode usar:

[Min(0)]

Isso imporá um valor mínimo necessário de 0 (zero) e nenhum valor máximo.

Você precisa DataAnnotationsExtensions para usar isso.


8
Não, eu não acho que isso esteja correto. Não faz parte da estrutura padrão do MVC3, mas sim da Data Annotations Extensions dataannotationsextensions.org . Forneça um link do MSDN.
Bernie Branca

1
NO - definitivamente não é parte da MVC 3 :( Mas essa biblioteca é uma extensão do bom ter qualquer maneira :)
Piotr Kula

1
Não faz parte do MVC3, mas não é importante. Se você deseja validação no lado do cliente, basta usar o pacote DataAnnotationsExtensions.MVC3. Esses dois pacotes estão disponíveis no nuget. Eu acho que é a melhor abordagem, pois você não tem uma mensagem de erro estúpida ou não precisa redefinir a mensagem de erro toda vez que deseja validar um número inteiro positivo ou decimal (o que é bastante comum).
Gentian

21

Se você trabalha com preços, tenho certeza de que pode assumir com segurança que nada custará mais de 1 trilhão de dólares.

Eu usaria:

[Range(0.0, 1000000000000)]

Ou, se você realmente precisar, basta colar o valor de Decimal.MaxValue(sem vírgulas):79,228,162,514,264,337,593,543,950,335

Qualquer um deles funcionará bem se você não for do Zimbábue.


7
Por que não apenas [Range(0.0,Decimal.MaxValue)]?
Coops

4
Não será compilado, Decimal.MaxValue não é uma constante.
John Farrell

Essa constante é um incômodo, referindo-se a um arquivo de recurso para texto de erro não é mais fácil
Coops

3
Agora você está assumindo que a moeda é dólar, não iene ou outra coisa.
Fred

1
@jfar Decimal.MaxValue É uma constante. Só que o Range não tem sobrecarga para acomodar um decimal.
Ε Г И І И О

11

Você pode usar a validação personalizada:

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

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

Tipo de métodos de validação:

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

Eu tentaria algo assim:

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

O problema de fazer isso, porém, é que o compilador deseja uma expressão constante, o que não permite ((double)0).ToString(). O compilador irá assumir

[Range(0d, (double)decimal.MaxValue, ErrorMessage = "Amount must be greater than zero.")]

Quem recusou isso explicaria por que você acha que minha solução é ruim ou não é útil? Porque apenas a votação sem explicação é totalmente inútil.
David T. Macknet

Sua mensagem de erro deve dizer "maior que ou igual a".
Ε Г И І И О

Boa pegada. Adicionado.
David T. Macknet

1

usando Range com

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

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

Espero que ajude


1

[Intervalo (0,01,100000000, ErrorMessage = "O preço deve ser maior que zero!")]


0

Eu diria que, decimal.MaxValue.ToString()como esse é o teto efetivo para o tipo decmial, é equivalente a não ter um limite superior.


4
O problema é que não é uma constante. Você obterá este erro: Um argumento atributo deve ser uma expressão constante, typeof expressão ou matriz expressão de criação de um tipo de parâmetro atributo
user169867

Como apontei abaixo, mas aparentemente não foi apreciado por alguém.
David T. Macknet
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.