DataAnnotation验证属性的Int或Number DataType

时间:2011-01-27 13:20:33

标签: asp.net-mvc asp.net-mvc-3 data-annotations

在我的MVC3项目中,我存储了足球/足球/曲棍球/ ...运动游戏的得分预测。因此,我的预测类的一个属性如下所示:

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

现在,在我的情况下,我还需要更改数据类型的错误消息int。使用了一些默认值 - “HomeTeamPrediction字段必须是数字。”。需要找到一种方法来更改此错误消息。此验证消息似乎也会对远程验证进行预测。

我尝试了[DataType]属性,但这似乎不是system.componentmodel.dataannotations.datatype枚举中的普通数字。

9 个答案:

答案 0 :(得分:194)

对于任何数字验证,您必须根据您的要求使用不同的范围验证:

For Integer

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

for float

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

表示双重

[Range(0, double.MaxValue, ErrorMessage = "Please enter valid doubleNumber")]

答案 1 :(得分:70)

尝试正则表达式

[RegularExpression("([0-9]+)")]      // for 0-inf or 
[RegularExpression("([1-9][0-9]*)"] // for 1-inf

希望它有所帮助:D

答案 2 :(得分:14)

在数据注释中使用正则表达式

[RegularExpression("([0-9]+)", ErrorMessage = "Please enter valid Number")]
public int MaxJsonLength { get; set; }

答案 3 :(得分:6)

尝试此属性:

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

此外,您还必须在验证器插件中注册该属性:

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

答案 4 :(得分:3)

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 :(得分:0)

差不多十年过去了,但该问题在Asp.Net Core 2.2中仍然有效。

我通过将data-val-number添加到消息中的使用本地化来对它进行管理:

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

答案 6 :(得分:0)

ASP.NET Core 3.1

这是我对该功能的实现,它可以在服务器端以及与自定义错误消息相同的jquery验证一起使用,就像其他任何属性一样:

属性:

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

客户端逻辑:

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

最后是用法:

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

答案 7 :(得分:0)

通过在视图模型中将属性设置为字符串,我能够绕过所有框架消息。

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

然后我需要在get方法中进行一些转换:

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

和发布方法:

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

这在使用range属性时效果最好,否则需要进行一些额外的验证以确保该值是数字。

您还可以通过将范围内的数字更改为正确的类型来指定数字的类型:

[Range(0, 10000000F, ErrorMessageResourceType = typeof(GauErrorMessages), ErrorMessageResourceName = nameof(GauErrorMessages.MoneyRange))]

答案 8 :(得分:0)

您可以编写自定义验证属性:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class Numeric : ValidationAttribute
{
    public Numeric(string errorMessage) : base(errorMessage)
    {
    }

    /// <summary>
    /// Check if given value is numeric
    /// </summary>
    /// <param name="value">The input value</param>
    /// <returns>True if value is numeric</returns>
    public override bool IsValid(object value)
    {
        return decimal.TryParse(value?.ToString(), out _);
    }
}

然后,您可以在您的财产上使用以下注释:

[Numeric("Please fill in a valid number.")]
public int NumberOfBooks { get; set; }