Int or Number DataType for DataAnnotation validation attribute

前端 未结 8 2430
我寻月下人不归
我寻月下人不归 2020-12-07 10:41

On my MVC3 project, I store score prediction for football/soccer/hockey/... sport game. So one of properties of my prediction class looks like this:

[Range(0         


        
相关标签:
8条回答
  • 2020-12-07 10:41

    ASP.NET Core 3.1

    This is my implementation of the feature, it works on server side as well as with jquery validation unobtrusive with a custom error message just like any other attribute:

    The attribute:

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

    Client side logic:

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

    And finally the Usage:

     [MustBeInteger(ErrorMessage = "You must provide a valid number")]
     public int SomeNumber { get; set; }
    
    0 讨论(0)
  • 2020-12-07 10:44

    I was able to bypass all the framework messages by making the property a string in my view model.

    [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 string HomeTeamPrediction { get; set; }
    

    Then I need to do some conversion in my get method:

    viewModel.HomeTeamPrediction = databaseModel.HomeTeamPrediction.ToString();
    

    and post method:

    databaseModel.HomeTeamPrediction = int.Parse(viewModel.HomeTeamPrediction);
    

    This works best when using the range attribute, otherwise some additional validation would be needed to make sure the value is a number.

    You can also specify the type of number by changing the numbers in the range to the correct type:

    [Range(0, 10000000F, ErrorMessageResourceType = typeof(GauErrorMessages), ErrorMessageResourceName = nameof(GauErrorMessages.MoneyRange))]
    
    0 讨论(0)
  • 2020-12-07 10:47
    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-07 10:51

    For any number validation you have to use different different range validation as per your requirements :

    For Integer

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

    for float

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

    for double

    [Range(0, double.MaxValue, ErrorMessage = "Please enter valid doubleNumber")]
    
    0 讨论(0)
  • 2020-12-07 10:55

    Try one of these regular expressions:

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

    hope it helps :D

    0 讨论(0)
  • 2020-12-07 10:57

    almost a decade passed but the issue still valid with Asp.Net Core 2.2 as well.

    I managed it by adding data-val-number to the input field the use localization on the message:

    <input asp-for="Age" data-val-number="@_localize["Please enter a valid number."]"/>
    
    0 讨论(0)
提交回复
热议问题