6

ASP.NET Core MVC has a great model binding & model validation subsystem which supports almost any scenario. But when developing APIs things can go a little more complicated.

Suppose we have a model class with a property XYZ which is annotated with [MinLength(5)].

public class ViewModel
{
    [MinLength(5)]
    public string XYZ { get; set; }
}

If anything goes wrong with this property what MVC will give you is something like this:

{ "XYZ": [ "The field XYZ must be a string or array type with minimum length of '5'" ] }

But this is not what the client needs! The client needs an object with specific details. She will create her own message however she wants to:

{ "error": "minLength", "property": "XYZ", "minimum": 5 }

Possible Solutions:

  1. You can use InvalidModelStateResponseFactory to generate customized responses. It gives you the ActionContext which contains the ModelState property. But all you can do is to process error messages which are pure strings! That could lead to some problems.
  2. Another option is to completely disable the MVC Validation and implement one for yourself.

I appreciate any other solutions.

1 Answer 1

5

For general validation message, it is pure string. And for minLength and minimum are different for different validation attribute. I am wondering how the client will check the different node.

For server side, InvalidModelStateResponseFactory would be better to return json object. and you need to check the ValidationAttribute for return different object like

services.Configure<ApiBehaviorOptions>(o =>
{
    o.InvalidModelStateResponseFactory = actionContext =>
    {
        var error = new Dictionary<string, string>();
        foreach (var key in actionContext.ModelState.Keys)
        {
            foreach (var parameter in actionContext.ActionDescriptor.Parameters)
            {
                var prop = parameter.ParameterType.GetProperty(key);
                if (prop != null)
                {
                    var attr = prop.GetCustomAttributes(typeof(ValidationAttribute), false).FirstOrDefault() as ValidationAttribute;
                    if (attr is MinLengthAttribute minLengthAttribute)
                    {
                        error.Add("Error", "minLength");
                        error.Add("Property", key);
                        error.Add("minimum", minLengthAttribute.Length.ToString());    
                    }
                }
            }
        }
        return new BadRequestObjectResult(error);
    };
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.