Model State in .NET Core (Explained Simply)

When we first start building API’s we make many assumptions about our users. We assume that they would never input bad data. This is very unrealistic.

Have you ever experienced the frustration of filling out a long form at the dentist office? This is the exact same feeling users have but it’s even greater because nobody is watching them!

This is why we must validate data constantly on both the front-end and the back-end.

ModelState works in tandem with data validation to provide the holy grail; Error Handling.

Things To Know Before Learning Model State

To prevent users from inputting incorrect data, we rely heavily on two things:

  • Model Binding with simple types

Model Binding is what turns a HTTP request from a string to useable programming constructs like int, string, bool. Model binding prevents users from passing in incorrect types (ex., passing in a string when it should be a bool). Except in very rare cases, ModelState will not interact with data binding via simple types. BUT it’s important to know because it relates to our next validation technique.

  • Model Binding with complex types

The difference between these two method signatures may not be clear at first, but they differ in what type of data is being passed. The method before we only passed in int and string. This method we are passing in entire objects!

Behind the scenes [ApiController] is parsing massive blocks of JSON and turning them into beautiful objects from which we can manipulate.

Model State

While this parsing is occurring, .NET is in the background checking to see whether these objects are correct. This is where ModelState comes into the picture.

Remember the [ApiController] annotation? Well, if .NET finds that something is wrong with the giant block of JSON passed it provides, it returns the ModelState with things that it found like:

  • User did not input enough data
  • User inputted too much data
  • User inputted a bad email

ModelState is technically just a giant object in the background that is provides us details of what went wrong with each request. Each endpoint method has it’s own and each request produces a new ModelState object.

You may be asking yourself, “Well, how does it even know?”.

[ApiController] does provide some error handling and validation out of the box, but it’s up to the developer to handle what should be classified as wrong.

This is what we have data annotation’s in our DTO and models (although having a data annotation in a model is a serious code smell).

Code like [Required],[MinLength],[MaxLength] coordinates with our ModelState to produces these errors and provide us with the necessary feedback for the front-end to consume.

Conclusion

While .NET does provide us with tons of out of the box tools to make our code better, it’s up to you to let ModelState know what is going wrong.

Happy coding!

Posted in C#

Leave a Reply

Your email address will not be published. Required fields are marked *