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.

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

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


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

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

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

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

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; }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.