我们如何从 ModelState 获取验证规则

How we can fetch validation rule from ModelState

是否可以从 ModelState 字典中获取验证规则。 例如

我的模型中有以下数据注释属性

[StringLength(64, MinimumLength = 8, ErrorMessage = "{0} must be between {2} to {1} characters")]
public string Password { get; set; }

那么在验证 Modelstate 时我们可以得到 MinimumLengthMaximumLenght 吗?

我想发送这两个值作为响应,以便前端可以使用这些值生成本地化消息。

我的回复示例如下

{
  "errorCode" : 1234,
  "message": : "Password must be between 8 to 64 characters",
  "args" : ["8","64"]
}

因此使用此错误代码前端可以使用 args.

生成本地化消息

So while validating Modelstate can we get MinimumLength and MaximumLenght?

您可以使用 Reflection 从模型类型中获取属性值。

var type = ViewModel.GetType()
var properties = type.GetProperties();
foreach (var property in properties)
    {
        var attributes = property.GetCustomAttributes(true);
        foreach (object attribute in attributes)
        {
            var stringLengthAttribute = attribute as StringLengthAttribute;
            if (stringLengthAttribute == null)
            {
              continue;
            }

            var maximumLength = stringLengthAttribute.MaximumLength;
            var minimumLength = stringLengthAttribute.MinimumLength;
        }
    }

即使我们添加也很难做到这一点 ConfigureApiBehaviorOptions 对象不包含验证规则 我建议最简单的方法是在你的字符串中创建一个 json 对象,这样你可以直接使用你想要的格式

 [StringLength(64, MinimumLength = 8, ErrorMessage = "{{error:'{0} must be between {2} to {1} characters ',args:'[{1},{2}]' }}") ]

您可以使用 Reflection 来实现您的要求,如@Józef Podlecki 所说。

也可以参考this.

下面是实现它的通用方法:

  public class PerInfo
    {
        [StringLength(64, MinimumLength = 8, ErrorMessage = "{0} must be between {2} to {1} characters")]
        public string Password { get; set; }
    }

作为您提供的响应格式,您可以创建一个错误模型:

 public class CusError
    {
        public long errorCode { get; set; }
        public string message { get; set; }
        public string[] args { get; set; }
    }

代码:

 [HttpPost]
        public IActionResult Validate(PerInfo perInfo)
        {
            if (!ModelState.IsValid)
            {
                var error = GenerateValidationModel<PerInfo>();
                return BadRequest(error);
            }
            return Ok();
        }

        private CusError GenerateValidationModel<T>()
        {
            var error = new CusError();
            foreach (var prop in typeof(T).GetProperties())
            {
                object[] attrs = prop.GetCustomAttributes(true);
                if (attrs == null || attrs.Length == 0)
                    continue;
                foreach (Attribute attr in attrs)
                {
                    if (attr is StringLengthAttribute)
                    {
                        error.errorCode = 1234;
                        error.message = string.Format((attr as StringLengthAttribute).ErrorMessage, prop.Name, (attr as StringLengthAttribute).MaximumLength.ToString(), (attr as StringLengthAttribute).MinimumLength.ToString());
                        error.args = new string[] { (attr as StringLengthAttribute).MinimumLength.ToString(), (attr as StringLengthAttribute).MaximumLength.ToString() };
                    }

                }
            }
            return error;
        }

这里是邮递员的测试结果: