Int o Number DataType para el atributo de validación DataAnnotation

111

En mi proyecto MVC3, almaceno la predicción de puntaje para fútbol / fútbol / hockey / ... juego deportivo. Entonces, una de las propiedades de mi clase de predicción se ve así:

[Range(0, 15, ErrorMessage = "Can only be between 0 .. 15")]
[StringLength(2, ErrorMessage = "Max 2 digits")]
[Remote("PredictionOK", "Predict", ErrorMessage = "Prediction can only be a number in range 0 .. 15")]
public int? HomeTeamPrediction { get; set; }

Ahora, también necesito cambiar el mensaje de error para un tipo de datos, inten mi caso. Se utiliza uno predeterminado: "El campo HomeTeamPrediction debe ser un número". Necesito encontrar una manera de cambiar este mensaje de error. Este mensaje de validación también parece tener una predicción para la validación remota uno.

Probé el [DataType]atributo, pero esto no parece ser un número simple en la system.componentmodel.dataannotations.datatypeenumeración.

Antonin Jelinek
fuente

Respuestas:

221

Para la validación de cualquier número, debe utilizar una validación de rango diferente según sus requisitos:

Para entero

[Range(0, int.MaxValue, ErrorMessage = "Please enter valid integer Number")]

para flotar

[Range(0, float.MaxValue, ErrorMessage = "Please enter valid float Number")]

por doble

[Range(0, double.MaxValue, ErrorMessage = "Please enter valid doubleNumber")]
Dilip0165
fuente
4
Esto no funcionó para mí en mi contexto. Si el usuario ingresa "asdf", [Range (typeof (decimal), "0", "9999.99", ErrorMessage = "El valor para {0} debe estar entre {1} y {2}")] lanza una excepción. Sin embargo, si lo hago [Range (typeof (decimal), "0.1", "9999.99", ErrorMessage = "El valor para {0} debe estar entre {1} y {2}")], el mensaje de error funcionará correctamente. 0 vs 0.1, no tiene sentido. error tal vez?
Efectivo el
1
Esta validación de "enteros" trata los valores que no son enteros como válidos (p. Ej., 0,3)
kevinpo
77

Pruebe una de estas expresiones regulares:

// for numbers that need to start with a zero
[RegularExpression("([0-9]+)")] 


// for numbers that begin from 1
[RegularExpression("([1-9][0-9]*)")] 

espero que ayude: D

Goran Žuri
fuente
13
¿No hay una forma más sencilla? Espero algo como: [Numeric (ErrorMessage = "Este campo debe ser un número")]
Banford
3
Lamentablemente no. Siempre puede escribir su propio atributo de validación.
Goran Žuri
2
Esta es la mejor solución, ya que cubre cadenas. int.MaxValuesolo cubre hasta2.147.483.647
Christian Gollhardt
19

Usar expresiones regulares en la anotación de datos

[RegularExpression("([0-9]+)", ErrorMessage = "Please enter valid Number")]
public int MaxJsonLength { get; set; }
Sathish
fuente
2
Esto parece funcionar bien en el contexto de la pregunta, siempre que la propiedad no sea int, sino string.
Paul
1
¿Por qué el paréntesis alrededor de la expresión regular? ¿Podría ser justo [0-9]+?
polkduran
5
public class IsNumericAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            decimal val;
            var isNumeric = decimal.TryParse(value.ToString(), out val);

            if (!isNumeric)
            {                   
                return new ValidationResult("Must be numeric");                    
            }
        }

        return ValidationResult.Success;
    }
}
stuartdotnet
fuente
5

Prueba este atributo:

public class NumericAttribute : ValidationAttribute, IClientValidatable {

    public override bool IsValid(object value) {
        return value.ToString().All(c => (c >= '0' && c <= '9') || c == '-' || c == ' ');
    }


    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.DisplayName),
            ValidationType = "numeric"
        };
        yield return rule;
    }
}

Y también debes registrar el atributo en el complemento validador:

if($.validator){
     $.validator.unobtrusive.adapters.add(
        'numeric', [], function (options) {
            options.rules['numeric'] = options.params;
            options.messages['numeric'] = options.message;
        }
    );
}
Stefan Turcanu
fuente
0

Pasó casi una década, pero el problema sigue siendo válido con Asp.Net Core 2.2 también.

Lo logré agregando data-val-numberal campo de entrada la localización de uso en el mensaje:

<input asp-for="Age" data-val-number="@_localize["Please enter a valid number."]"/>
Laz Ziya
fuente
0

ASP.NET Core 3.1

Esta es mi implementación de la función, funciona en el lado del servidor, así como con la validación de jquery discreta con un mensaje de error personalizado como cualquier otro atributo:

El atributo:

  [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class MustBeIntegerAttribute : ValidationAttribute, IClientModelValidator
    {
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            var errorMsg = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, "data-val-mustbeinteger", errorMsg);
        }

        public override bool IsValid(object value)
        {
            return int.TryParse(value?.ToString() ?? "", out int newVal);
        }

        private bool MergeAttribute(
              IDictionary<string, string> attributes,
              string key,
              string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }

Lógica del lado del cliente:

$.validator.addMethod("mustbeinteger",
    function (value, element, parameters) {
        return !isNaN(parseInt(value)) && isFinite(value);
    });

$.validator.unobtrusive.adapters.add("mustbeinteger", [], function (options) {
    options.rules.mustbeinteger = {};
    options.messages["mustbeinteger"] = options.message;
});

Y finalmente el uso:

 [MustBeInteger(ErrorMessage = "You must provide a valid number")]
 public int SomeNumber { get; set; }
HMZ
fuente