I have found that most projects I have worked on with ASP.Net Web API have required a custom model returned when certain preconditions have not been met such as missing properties etc. In ASP.Net MVC we can utilise DataAnnotations on our models which nicely validates the model and populates the ModelStateDictionary for us, we then return the model to the view and all is good. This is on top of the fact that it can also generate client side validation for us as well, all in all a really nicely packaged solution.
In WebAPI we can use DataAnnotations however by default this will not return a failing response without some manual intervention. Hooking up an action filter to return the model state dictionary as the response is pretty straight forward however so far I have not come across a client who would be happy to return the model state dictionary serialized structure:
{ "testModel.Name":{ "Value":null, "Errors":[ {"Exception":null,"ErrorMessage":"The Name field is required."} ]}, "testModel.Age":{ "Value":null, "Errors":[ {"Exception":null,"ErrorMessage":"The field Age must be between 10 and 20."} ]} }
Well, there are plenty of ways this can be solved, in my case it has quite often been custom validation services injected into the controller or custom per app versions of the new library I am about to show you. I have packaged up my most common cases into a library called the ASP.Net Web API Request Validator which can be found on NuGet https://www.nuget.org/packages/ASPNetWebAPIRequestValidator. There are a number of ways it can be used, in this post I will show you a fairly simple but most common case where the information within the ModelStateDictionary is returned in a custom model. For more ways to use the library, check out the documentation at http://embarr-development.co.uk/labs/asp-net-web-api-validator. The source is available at BitBucket: https://bitbucket.org/embarr-development/asp.net-web-api-request-validator.
Lets say we want to create a nice simple structure which would return the following style output:
[ { "Property" : "Name", "ErrorMessages" : [ { "Message" : "The Name field is required." } ] }, { "Property" : "Age", "ErrorMessages" : [ { "Message" : "The field Age must be between 10 and 20." } ] } ]
Create the following models:
public class ValidationError { public string Property { get; set; } public List<Error> ErrorMessages { get; set; } public ValidationError() { ErrorMessages = new List<Error>(); } }
public class Error { public string Message { get; set; } }
These models will form the structure of each validation error, so essentially you will receive an array of these as the validation error response.
Make sure you have pulled in the library via NuGet https://www.nuget.org/packages/ASPNetWebAPIRequestValidator. In your WebApiConfig class or Application_Start method (or wherever you like to set up your web api cofiguration) add the following code:
RequestValidator.Create<ValidationError>() .MapPropertyName(x => x.Property) .MapPropertyErrorMessagesCollection(x => x.Errors) .Map(x => x.Message).ToErrorMessage() .Init(config);
Explanation:
At this point you are hooked up and ready to go, create an API controller with a model with some DataAnnotation for example:
public class MyModel { [Required] public string Name { get; set; } [Range(10, 20)] public int Age { get; set; } }
Spin up your solution and send a request which will fail the validation DataAnnotations you have added and voila, you will receive the model state errors in your custom serialized format. Hope you find this useful, let me know if you have any issues or suggestions for improvements.