ASP.NET Core Web API 中整数值的自定义模型验证器 [英] Custom Model Validator for Integer value in ASP.NET Core Web API

查看:27
本文介绍了ASP.NET Core Web API 中整数值的自定义模型验证器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个自定义验证器属性类,用于检查模型类中的整数值.但问题是这个类不起作用.我已经调试了我的代码,但在调试代码期间没有命中断点.这是我的代码:

I have developed a custom validator Attribute class for checking Integer values in my model classes. But the problem is this class is not working. I have debugged my code but the breakpoint is not hit during debugging the code. Here is my code:

public class ValidateIntegerValueAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                int output;

                var isInteger = int.TryParse(value.ToString(), out output);

                if (!isInteger)
                {
                    return new ValidationResult("Must be a Integer number");
                }
            }

            return ValidationResult.Success;
        }
    }

我还有一个过滤器类,用于在应用程序请求管道中进行全局模型验证.这是我的代码:

I have also an Filter class for model validation globally in application request pipeline. Here is my code:

public class MyModelValidatorFilter: IActionFilter
{   
    public void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.ModelState.IsValid)
            return;

        var errors = new Dictionary<string, string[]>();

        foreach (var err in actionContext.ModelState)
        {
            var itemErrors = new List<string>();

            foreach (var error in err.Value.Errors){
                itemErrors.Add(error.Exception.Message);
            }

            errors.Add(err.Key, itemErrors.ToArray());
        }

        actionContext.Result = new OkObjectResult(new MyResponse
        {
            Errors = errors
        });
    }
}

带有验证的模型类如下:

The model class with validation is below:

public class MyModelClass

{

[ValidateIntegerValue(ErrorMessage = "{0} must be a Integer Value")]
[Required(ErrorMessage = "{0} is required")]
public int Level { get; set; }        

}

谁能告诉我为什么属性整数验证类不起作用.

Can anyone please let me know why the attribute integer validation class is not working.

推荐答案

模型验证在模型从请求中反序列化后开始发挥作用.如果模型包含整数字段 Level 并且您发送的值无法反序列化为整数(例如abc"),那么模型甚至不会被反序列化.因此,也不会调用验证属性 - 只是没有验证模型.

Model validation comes into play after the model is deserialized from the request. If the model contains integer field Level and you send value that could not be deserialized as integer (e.g. "abc"), then model will not be even deserialized. As result, validation attribute will also not be called - there is just no model for validation.

这样看来,实现这样的ValidateIntegerValueAttribute并没有多大意义.在这种情况下,这种验证已经由反序列化器 JSON.Net 执行.您可以通过检查控制器操作中的模型状态来验证这一点.ModelState.IsValid 将设置为 false 并且 ModelState 错误包将包含以下错误:

Taking this, there is no much sense in implementing such ValidateIntegerValueAttribute. Such validation is already performed by deserializer, JSON.Net in this case. You could verify this by checking model state in controller action. ModelState.IsValid will be set to false and ModelState errors bag will contain following error:

Newtonsoft.Json.JsonReaderException:无法将字符串转换为整数:abc.路径级别",...

Newtonsoft.Json.JsonReaderException: Could not convert string to integer: abc. Path 'Level', ...

还要补充一点:为了使 Required 验证属性正确工作,您应该使基础属性可以为空.如果没有这个,在模型反序列化之后,该属性将保留其默认值 (0).模型验证无法区分遗漏值和等于默认值的值.所以为了 Required 属性的正确工作,使属性可以为空:

One more thing to add: for correct work of Required validation attribute, you should make the underlying property nullable. Without this, the property will be left at its default value (0) after model deserializer. Model validation has no ability to distinguish between missed value and value equal to default one. So for correct work of Required attribute make the property nullable:

public class MyModelClass
{
    [Required(ErrorMessage = "{0} is required")]
    public int? Level { get; set; }
}

这篇关于ASP.NET Core Web API 中整数值的自定义模型验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆