Consolidate Model Validation Errors as a Single String in ASP.NET Web API

As we all know that we can do validation in ASP.NET MVC by decorating the model with validation attributes and when the page is generated by the framework it will automatically generate the client side validation scripts. You can read more about it in the Microsoft Documentation here. Normally the output will be like in the figure given below.

Let's see how we can use the same mechanism in ASP.NET WebAPI to do the validation. I have created a model class as shown below

public class Employee
    {
        [Required]
        [MaxLength(50, ErrorMessage="First name should not exceed 50 characters")]
        public string FirstName { get; set; }
        [Required]
        [MaxLength(50, ErrorMessage="Last name should not exceed 50 characters")]
        public string LastName { get; set; }
        [Required]
        [MaxLength(200, ErrorMessage="Address should not exceed 200 characters")]
        public string Address { get; set; }
        [Required]
        [EmailAddress(ErrorMessage="Email is invalid")]
        [MaxLength(50, ErrorMessage="EmailAddress should not exceed 50 characters")]
        public string EmailAddress { get; set; }
    }

And created a POST method as given below which basically validates the model and if any errors are found then returns an error as response.

public HttpResponseMessage Post([FromBody] Employee emp)
        {
            if (!ModelState.IsValid)
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ModelState);
            return Request.CreateResponse(HttpStatusCode.Created, emp);
        }

Let's test this method by using POSTMAN which is a wonderful utility for testing WebAPI's. If you want to know more about it please refer the documentation here. In this case I am sending only the FirstName property so that the validation will fail and will return the validation messages as response.

'

If you look at the response, you will see that you got a model object in return which has the list of properties failed along with the error messages. If you want to show this message in the UI, it won't provide good UX to the user. It is not at all recommended to manipulate with these objects in your client side application because if we make any changes in the model in the WebAPI side then you have to make the necessary changes in places where you consume the API.

We can manipulate this at the API side by writing a Filter as in ASP.NET MVC. In this I got hold of the ModelState dictionary object and then flattened the object to a comma seperated string.

public class ValidationAttributeFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {

            var modelState = actionContext.ModelState;
            var errorMessages = new StringBuilder();
            if (!modelState.IsValid)
            {



                var list = modelState.ToDictionary(x => x.Key, y => y.Value.Errors.Select(x => x.ErrorMessage).ToArray())
                  .Where(m => m.Value.Count() > 0);
                var message = new StringBuilder();
                foreach (var itm in list)
                {

                    message.Append(string.Concat(string.Join(",", itm.Value.ToArray()), ", "));
                }


                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, message.ToString());
            }
            else if (actionContext.ActionArguments.FirstOrDefault().Value == null)
            {



                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, "Please pass all the required fields");
            }
            base.OnActionExecuting(actionContext);
        }


    }

Now you need to add this to the pipeline and that can be done from WebApi.config file

config.Filters.Add(new ModelValidationAttribute());

Now let's see what will be the response for the same request which I used earlier. You can see that now the response is a single string which has got all the validation error messages as a single string.


No Comments

Add a Comment