1

Is there anyway to fetch the validation rule from ModelState dictionary. For example

I have following data annotation attribute in my model

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

So while validating Modelstate can we get MinimumLength and MaximumLenght?

I want to send both of these values in response so front-end can generate localize message using these values.

my sample response is as follow

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

So using this error code front end can generate localize message using args.

Kirk Larkin
  • 84,915
  • 16
  • 214
  • 203
Tech Yogesh
  • 427
  • 4
  • 18

3 Answers3

1

It's difficult to make this even if we add ConfigureApiBehaviorOptions the object doesn't contains validation rules i would suggest the easiest way is to make a json object inside your string , and like this you can use directly in the format that you want

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

You can use Reflection to achieve your requirement as @Józef Podlecki said.

You can also refer to this.

Here is a generic method to achieve it:

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

As the response format you provided, you can create a error model:

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

Code:

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

Here is the test result by postman:

enter image description here

LouraQ
  • 6,443
  • 2
  • 6
  • 16
0

So while validating Modelstate can we get MinimumLength and MaximumLenght?

You can get attribute values from model type with 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;
        }
    }

Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50