I recently started using the
IValidatableObject interface in my .NET Core APIs to encapsulate validation logic. This helps me separate concerns and keep my controllers lean. For example, suppose that we need to write an endpoint that returns all items for a given day…
One option would be to write a GET method that takes in a
resourceGroup input parameters. This works, but the problem is that the validation logic for the parameters would result in extra code in your controller and ideally, we want our controllers to be as lean as possible.
A better option is to use a POST endpoint that receives a JSON object that corresponds to a C# model that extends the
IValidatableObject interface. Suppose your API takes in the following data:
You could create a class in C# that models this data and accept it via an [HttpPost] endpoint. To do this you would create the POCO model of the JSON above and extend the IValidatableObject interface. When you implement this interface, you implement the Validate() method, in which you can build custom validations and return any errors via the List. Generic checks for things like required pieces of data or string length can be performed through annotations as shown below:
So when someone hits your endpoint, if the payload does not match your validations, the consumer of your endpoint will receive a list of errors. There are some nuances in order to get this pattern right, but for the most part, it’s pretty straight forward. You need to play with it for a bit and then you’ll get it.
By taking this approach, we can now accept richer JSON queries through our endpoint and encapsulate the validation logic in the C# query model. This makes the controller look much leaner and our code cleaner.
Bottom line is: leave parameter validation code out of your controller and let the framework handle it by extending IValidatableObject.
Thanks for reading and happy coding!